拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 将时间戳转换为特定时区的日期时间

将时间戳转换为特定时区的日期时间

白鹭 - 2022-02-16 2123 0 0

我想将时间戳转换(which is in GMT)local date and time.

这是我到目前为止实施的,但它给了我错误的月份

Timestamp stp = new Timestamp(1640812878000L);
Calendar convertTimestamp = convertTimeStamp(stp,"America/Phoenix");
System.out.println(convertTimestamp.getTime());
    

public static Calendar convertTimeStamp( Timestamp p_gmtTime, String p_timeZone) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:MM:SS a", Locale.ENGLISH);
        DateFormat formatter = DateFormat.getDateTimeInstance();
        if (p_timeZone != null) {
            formatter.setTimeZone(TimeZone.getTimeZone(p_timeZone));
        } else {
            formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
        }

        String gmt_time = formatter.format(p_gmtTime);
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(gmt_time));
        return cal;
    }

任何帮助,将不胜感激。

uj5u.com热心网友回复:

您不能将时间戳转换为另一个时区,因为时间戳始终是格林威治标准时间,它们是宇宙中时间线中的给定时刻。

我们人类习惯于地球上的当地时间,因此可以将时间戳格式化为更具人类可读性,并在这种情况下将其转换为当地时区。

使用遗留的 java.util.* 包,这是按如下方式完成的:

DateFormat tzFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
tzFormat.setTimeZone(TimeZone.getTimeZone("CET")); // Use whatever timezone
System.out.println(tzFormat.format(date));

如果您需要对本地时区的时间戳进行“数学运算”(例如,本地时区明天 8:00),那么情况会更加复杂。

为此,您可以使用一些技巧(例如决议或修改使用上述方法获得的字符串),或使用具有特定类的新 Java 日期和时间类来处理本地时区中的日期和时间:

Instant timestamp = Instant.ofEpochMilli(inputValue);
ZonedDateTime romeTime = timestamp.atZone(ZoneId.of("Europe/Rome"));

请注意第二个示例如何使用“欧洲/罗马”而不是一般的“CET”。如果您打算处理使用 DST 的时区,这一点非常重要,因为即使它们处于同一时区,DST 更改日(或者是否使用 DST)也可能会因国家/地区而异。

uj5u.com热心网友回复:

tl;博士

Instant
.ofEpochMilli(                       // Parse a count of milliseconds since 1970-01-01T00:00Z.
    1_640_812_878_000L
)                                    // Returns a `Instant` object.
.atZone(                             // Adjust from UTC to a time zone. Same moment, same point on the timeline, different wall-clock time.
    ZoneId.of( "America/Phoenix" ) 
)                                    // Returns a `ZonedDateTime` object.
.format(                             // Generat text representing the date-time value kept within that `ZonedDateTime` object.
    DateTimeFormatter
    .ofLocalizedDateTime( FormatStyle.MEDIUM )
    .withLocale( Locale.US ) 
)                                    // Returns a `String` object.

在 IdeOne.com 上查看此代码的实时运行情况

细节

您使用的是几年前由现代所取代可怕旧日期-时间类java.time在JSR 310切勿使用定义的类TimestampCalendarDateSimpleDateFormat,等。

使用Instant该类表示以 UTC 显示的时刻,偏移量为零时-分-秒。

long millisecondsSinceBeginningOf1970InUtc = 1_640_812_878_000L ;
Instant instant = Instant.ofEpochMilli( millisecondsSinceBeginningOf1970InUtc ) ;

指定您感兴趣的时区。

ZoneID z = ZoneId.of( "Africa/Tunis" ) ;

从零偏移调整到该时区以生成ZonedDateTime物件。

ZonedDateTime zdt = instant.atZone( z ) ;

通过自动本地化生成代表那个时刻的文本。使用 aLocale指定在翻译中使用的人类语言以及在决定缩写、大小写、元素顺序等时使用的文化。

Locale locale = Locale.JAPAN ; // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ).withLocale( locale ) ;
String output = zdt.format( f ) ;

所有这些都在 Stack Overflow 上多次解决。搜索以了解更多信息。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *