Java将毫秒时间戳转换为与给定时区相关的日期

时间:2018-02-09 21:27:15

标签: java date simpledateformat date-formatting timezone-offset

我已经看到了很多这方面的资源,但我无法得到的一件事是转换毫秒时间戳,我在转换过程中如何添加相应的时区。

Date date = new Date(Long.valueOf(dateInMil*1000L);
SimpleDateFormat myDate = new SimpleDateFormat("EEE, MMM d, ''yy");
String formatted = myDate.format(date);

现在,如果我在字符串格式中有时区/偏移量,即" -04:00"或" +2:00"如何将它应用到上面所以我可以得到正确的日期?

4 个答案:

答案 0 :(得分:4)

TL;博士

Instant.ofEpochMilli( myCountOfMilliseconds ) 
       .atZone( ZoneId.of( "Africa/Tunis" ) )
       .toString()

java.time

现代方法使用 java.time 类,而不是现在遗留下来的麻烦的旧Calendar / Date类。

假设你的毫秒计数是自epoch reference(1970-01-01T00:00)1970年第一时刻UTC以来的计数,则解析为Instant。< / p>

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.ofEpochMilli( myCountOfMilliseconds ) ;

要从UTC移至其他时区,请应用ZoneId获取ZonedDateTime

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

对象与文本

分配时区后,然后生成所需格式的字符串(而不是之前)。您可能会将日期时间值(对象)与表示文本值的字符串混淆。学会思考智能对象,而不是愚蠢的字符串。

DateTimeFormatter

要以特定格式生成字符串,请使用DateTimeFormatter。搜索Stack Overflow已被多次覆盖,这里显示的其他概念也是如此。特别值得注意的是DateTimeFormatter.ofLocalized…方法。

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:2)

我在之前的项目中做了类似的事情。你可以使用SimpleDateFormat类的setTimeZone方法。像这样:

mydate.setTimeZone(TimeZone.getTimeZone("GMT -0400"));

答案 2 :(得分:2)

    DateTimeFormatter myDateFormatter
            = DateTimeFormatter.ofPattern("EEE, MMM d, ''yy", Locale.ENGLISH);
    long dateInSec = 1_554_321_098L;
    String utcOffsetString = "-04:00";
    ZoneOffset offset = ZoneOffset.of(utcOffsetString);
    String date = Instant.ofEpochSecond(dateInSec)
            .atOffset(offset)
            .format(myDateFormatter);
    System.out.println(date);

打印

Wed, Apr 3, '19

您提供的另一个示例偏移+2:00稍微困难一些,因为ZoneOffset.of只需要小时(+2)或冒号前两位数小时({{1} })。一种解决方案是在将字符串交给+02:00之前修复字符串:

ZoneOffset

结果仍为 String utcOffsetString = "+2:00"; utcOffsetString = utcOffsetString.replaceFirst("([-+])(\\d:\\d{2})", "$10$2"); ZoneOffset offset = ZoneOffset.of(utcOffsetString); 。如果字符串中已有2位数小时,Wed, Apr 3, '19将不会替换任何内容,因此您只需返回相同的字符串。

如果我将偏移更改为replaceFirst,我会改为+08:00

编辑:我坦率地发现我用来修复偏移字符串的正则表达式非常难以理解。这是一种更简单的修复方法:

Thu, Apr 4, '19

像Basil Bourque我正在使用java.time。查看his answer中的所有详细信息。

答案 3 :(得分:1)

不完全是你想要的但是关闭

String timeZone = "America/Los_Angeles"
TimeZone tz = TimeZone.getTimeZone(timeZone);
SimpleDateFormat sdf = new SimpleDateFormat("EEEEE MMMMM d hh:mm a");
sdf.setTimeZone(tz);

Date localizedTime = sdf.format(new Date());

如果保留本地化字符串而不是偏移量,这将起作用。或者你可以制作地图。