Java时间转换的方法(2)

  验收标准:不论时间数据按照哪个时区输入,存储为GMT/UTC+0时区同时刻的毫秒级整型时间戳,用户能够感知到的时间都按照工程时区来呈现和输出。

5 示例

  代码示例只为说明问题,不好勿喷。

1)Java8之前的解决方案 (1)转换工具类——DateTimeUtil

package dateTime;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import org.apache.commons.lang.StringUtils;

public class DateTimeUtil

{

/**

* datetime format

*/

public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";

/**

* REGEX_DATETIME

*/

private static final String REGEX_DATETIME = "^((\\d{2}(([02468][048])|([13579][26]))[\\-]?"

+ "((((0?[13578])|(1[02]))[\\-]?((0?[1-9])|([1-2][0-9])|(3[01])))"

+ "|(((0?[469])|(11))[\\-]?((0?[1-9])|([1-2][0-9])|(30)))"

+ "|(0?2[\\-]?((0?[1-9])|([1-2][0-9])))))"

+ "|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-]?"

+ "((((0?[13578])|(1[02]))[\\-]?((0?[1-9])|([1-2][0-9])|(3[01])))"

+ "|(((0?[469])|(11))[\\-]?((0?[1-9])|([1-2][0-9])|(30)))"

+ "|(0?2[\\-]?((0?[1-9])|(1[0-9])|(2[0-8]))))))" + "\\s"

+ "(((0?[0-9])|(1[0-9])|(2[0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9]))))?$";

/**

* convertToUtcTimeStamp<br>

* 将关注对象所在地的时间"yyyy-MM-dd HH:mm:ss"转换为UTC+0的毫秒级整型时间戳

* 关注对象所在地时区最好与工程时区相同,

* 但如果关注对象所在范围跨时区,关注对象所在地时区与工程时区也可以不同,

* 但这样呈现的时间数据会与输入有差别,其含义是与关注对象持续时间同时刻的工程时区的时间。

* 时间处理原则:不论时间数据按照哪个时区输入,

* 存储为UTC+0时区同时刻的毫秒级整型时间戳,用户能够感知到的时间都按照工程时区来呈现。

* @param strDateTime 关注对象所在地的时间"yyyy-MM-dd HH:mm:ss"

* @param iTimeZoneInMilliSec 关注对象所在地时区偏移量(毫秒级整型时间戳)

* @param iDstInMilliSec 关注对象所在地夏令时偏移量(毫秒级整型时间戳)

* @return UTC+0的毫秒级整型时间戳

*/

public static long convertToUtcTimeStamp(String strDateTime,

long iTimeZoneInMilliSec,

long iDstInMilliSec)

{

if (StringUtils.isEmpty(strDateTime) || !strDateTime.matches(REGEX_DATETIME))

{

return 0L;

}

Date oTime = null;

try

{

oTime = parseToDate(strDateTime);

}

catch (Exception e)

{

e.getMessage();

}

long iTimeStamp = 0L;

if (null != oTime)

{

iTimeStamp = oTime.getTime();

}

Calendar oCalendar = Calendar.getInstance(); // 获取当前日历对象

long iServerTimeZoneOffset = oCalendar.get(Calendar.ZONE_OFFSET); // 获取当前时区偏移量

long iServerDSTOffset = oCalendar.getTimeZone().getDSTSavings(); // 获取当前夏令时偏移量

// 计算UTC+0的毫秒级整型时间戳

long iUtcTimeStamp = iTimeStamp + iServerTimeZoneOffset + iServerDSTOffset

- iTimeZoneInMilliSec - iDstInMilliSec;

return iUtcTimeStamp;

}

/**

* convertToPrjDateTime<br>

* 将UTC+0的毫秒级整型时间戳转换为工程时区的时间"yyyy-MM-dd HH:mm:ss"<br/>

* @param iUtcTimeStamp UTC+0的毫秒级整型时间戳

* @param iPrjTimeZoneInMilliSec 工程时区偏移量(毫秒级整型时间戳)

* @param iPrjDstInMilliSec 工程夏令时偏移量(毫秒级整型时间戳)

* @return 工程时区的时间"yyyy-MM-dd HH:mm:ss"

*/

public static String convertToPrjDateTime(long iUtcTimeStamp,

long iPrjTimeZoneInMilliSec,

long iPrjDstInMilliSec)

{

Calendar oCalendar = Calendar.getInstance(); // 获取当前日历对象

long iServerTimeZoneOffset = oCalendar.get(Calendar.ZONE_OFFSET); // 获取当前时区偏移量

long iServerDSTOffset = oCalendar.getTimeZone().getDSTSavings(); // 获取当前夏令时偏移量

// 计算工程时区的时间

String strPrjDateTime = "";

Date oPrjDateTime = new Date(iUtcTimeStamp - iServerTimeZoneOffset - iServerDSTOffset

+ iPrjTimeZoneInMilliSec + iPrjDstInMilliSec);

strPrjDateTime = dateFormat(YMDHMS, oPrjDateTime);

return strPrjDateTime;

}

/**

* parseToDate

* @param value TimeStamp / 年-月-日 时:分:秒

* @return Date

* @throws Exception

*/

private static Date parseToDate(String value) throws Exception

{

Date date = null;

try

{

Long dataValue = Long.valueOf(value);

date = new Date(dataValue);

}

catch (Exception e)

{

date = parseDate(value, YMDHMS);

}

return date;

}

/**

* parseDate

* @param strDate 年-月-日 时:分:秒

* @param strFormat yyyy-MM-dd HH:mm:ss

* @return Date

* @throws Exception

*/

private static Date parseDate(String strDate, String strFormat) throws Exception

{

if (StringUtils.isEmpty(strFormat))

{

strFormat = YMDHMS;

}

DateFormat sdf = new SimpleDateFormat(strFormat);

return sdf.parse(strDate);

}

/**

* dateFormat

* @param strFormat yyyy-MM-dd HH:mm:ss

* @param oDate Date

* @return 年-月-日 时:分:秒

*/

private static String dateFormat(String strFormat, Date oDate)

{

SimpleDateFormat sdf = new SimpleDateFormat(strFormat);

String strDate = sdf.format(oDate);

return strDate;

}

}

 

(2)转换Demo——DateTimeTest

package DateTimeTest;

public class DateTimeTest

{

publicstaticvoid main(String[] args)

{

new DateTimeTest();

}

public DateTimeTest()

{

testConvertDateTime();

}

/**

* 测试日期时间转换不应该受到系统时区的影响。

* 无论系统部署在哪个时区,都应该准确存储GMT时间戳,呈现工程时区下的年-月-日 时:分:秒

*/

privatevoid testConvertDateTime()

{

String strDateTime01 = "2015-07-04 20:30:00";

longiDateTime01 = DateTimeUtil.convertToUtcTimeStamp(strDateTime01, 28800000l, 0);

System.out.println(iDateTime01);

longiDateTime02 = 1436013000000L;

String strDateTime02 = DateTimeUtil.convertToPrjDateTime(iDateTime02, 28800000l, 0);

System.out.println(strDateTime02);

}

}

2)Java8之后的解决方案 (1)转换工具类——ZonedDateTimeUtil

package dateTime;

import org.apache.commons.lang.StringUtils;

import java.time.Instant;

import java.time.LocalDateTime;

import java.time.ZoneId;

import java.time.ZonedDateTime;

import java.time.format.DateTimeFormatter;

public class ZonedDateTimeUtil {

public static enum EnumDateTimeFormatter {

YMDHMS("yyyy-MM-dd HH:mm:ss", 1),

YMD("yyyy-MM-dd", 2),

HMS("HH:mm:ss", 3);

String name = "";

int index = 0;

private EnumDateTimeFormatter(String name, int index) {

this.name = name;

this.index = index;

}

public String getInfo() {

return this.name;

}

}

public static enum EnumZone {

ZONE_0("+00:00", 0),

ZONE_EAST1("+01:00", 1),

ZONE_EAST2("+02:00", 2),

ZONE_EAST3("+03:00", 3),

ZONE_EAST4("+04:00", 4),

ZONE_EAST5("+05:00", 5),

ZONE_EAST6("+06:00", 6),

ZONE_EAST7("+07:00", 7),

ZONE_EAST8("+08:00", 8),

ZONE_EAST9("+09:00", 9),

ZONE_EAST10("+10:00", 10),

ZONE_EAST11("+11:00", 11),

ZONE_EAST12("+12:00", 12),

ZONE_EAST13("+13:00", 13),

ZONE_WEST1("-01:00", 101),

ZONE_WEST2("-02:00", 102),

ZONE_WEST3("-03:00", 103),

ZONE_WEST4("-04:00", 104),

ZONE_WEST5("-05:00", 105),

ZONE_WEST6("-06:00", 106),

ZONE_WEST7("-07:00", 107),

ZONE_WEST8("-08:00", 108),

ZONE_WEST9("-09:00", 109),

ZONE_WEST10("-10:00", 110),

ZONE_WEST11("-11:00", 111),

ZONE_WEST12("-12:00", 112);

String name = "";

int index = 0;

private EnumZone(String name, int index) {

this.name = name;

this.index = index;

}

public String getInfo() {

return this.name;

}

}

/**

* convertToUtcTimeStamp

* 将关注对象所在地的时间"yyyy-MM-dd HH:mm:ss"转换为UTC+0的毫秒级整型时间戳

* <p>

* 关注对象所在地时区最好与工程时区相同,

* 但如果关注对象所在范围跨时区,关注对象所在地时区与工程时区也可以不同,

* 但这样呈现的时间数据会与输入有差别,其含义是与关注对象持续时间同时刻的工程时区的时间。

* 时间处理原则:不论时间数据按照哪个时区输入,

* 存储为UTC+0时区同时刻的毫秒级整型时间戳,用户能够感知到的时间都按照工程时区来呈现和输出。

*

* @param strDateTime          关注对象所在地的时间"yyyy-MM-dd HH:mm:ss"

* @param enumDateTimeFormatter 时间格式

* @param enumZone              工程时区

* @return UTC+0的毫秒级整型时间戳

*/

public static long convertToUtcTimeStamp(String strDateTime,

EnumDateTimeFormatter enumDateTimeFormatter,

EnumZone enumZone) {

if (StringUtils.isEmpty(strDateTime)

|| null == enumDateTimeFormatter

|| null == enumZone) {

return 0L;

}

long iDateTime = ZonedDateTime.parse(

strDateTime,

DateTimeFormatter.ofPattern(enumDateTimeFormatter.getInfo()).withZone(ZoneId.of(enumZone.getInfo())))

.toInstant()

.toEpochMilli();

return iDateTime;

}

/**

* convertToPrjDateTime

* 将UTC+0的毫秒级整型时间戳转换为工程时区的时间"yyyy-MM-dd HH:mm:ss"

*

* @param iDateTime            UTC+0的毫秒级整型时间戳

* @param enumDateTimeFormatter 时间格式

* @param enumZone              工程时区

* @return 工程时区的时间"yyyy-MM-dd HH:mm:ss"

*/

public static String convertToPrjDateTime(long iDateTime,

EnumDateTimeFormatter enumDateTimeFormatter,

EnumZone enumZone) {

if (null == enumDateTimeFormatter

|| null == enumZone) {

return "";

}

String strDateTime = LocalDateTime.ofInstant(

Instant.ofEpochMilli(iDateTime), ZoneId.of(enumZone.getInfo()))

.format(DateTimeFormatter.ofPattern(enumDateTimeFormatter.getInfo()));

return strDateTime;

}

}

(2)转换Demo——ZonedDateTimeTest

package dateTime;

public class ZonedDateTimeTest {

public static void main(String[] args) {

new ZonedDateTimeTest();

}

public ZonedDateTimeTest() {

test();

}

private void test() {

String strDateTime01 = "2015-07-04 20:30:00";

long iDateTime02 = 1436013000000L;

// java8灏佽

long iDateTime = ZonedDateTimeUtil.convertToUtcTimeStamp(strDateTime01,

ZonedDateTimeUtil.EnumDateTimeFormatter.YMDHMS,

ZonedDateTimeUtil.EnumZone.ZONE_EAST8);

System.out.println(iDateTime);

String strDateTime = ZonedDateTimeUtil.convertToPrjDateTime(iDateTime02,

ZonedDateTimeUtil.EnumDateTimeFormatter.YMDHMS,

ZonedDateTimeUtil.EnumZone.ZONE_EAST8);

System.out.println(strDateTime);

String strDateTime1 = ZonedDateTimeUtil.convertToPrjDateTime(iDateTime02,

ZonedDateTimeUtil.EnumDateTimeFormatter.YMD,

ZonedDateTimeUtil.EnumZone.ZONE_EAST8);

System.out.println(strDateTime1);

String strDateTime2 = ZonedDateTimeUtil.convertToPrjDateTime(iDateTime02,

ZonedDateTimeUtil.EnumDateTimeFormatter.HMS,

ZonedDateTimeUtil.EnumZone.ZONE_EAST8);

System.out.println(strDateTime2);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/07e9136756b3488bef2f26d913bef8c3.html