首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将偏移整数映射到IANA时区

如何将偏移整数映射到IANA时区
EN

Stack Overflow用户
提问于 2022-07-15 15:36:36
回答 3查看 195关注 0票数 4

使用存储历史对象时区信息的系统如下:

代码语言:javascript
复制
o1:    dt= 2022-07-15 13:32:00  offset=5   dst=false    
o2:    dt= 2022-01-15 13:32:00  offset=5   dst=true     
o3:    dt= 2022-07-15 13:32:00  offset=7   dst=false    

如果把“美国/纽约”这样的时区储存起来,生活会容易得多,但这正是我必须面对的。我的最终目标是将这些历史日期与当前时间进行比较,并得到它们之间的时间差。

创建当前时间很容易。我可以在UTC买到

代码语言:javascript
复制
   ZonedDateTime.now(ZoneId.of("UTC"))
   2022-07-15T15:33:04.177Z[UTC]

或者我的本地时区

代码语言:javascript
复制
ZonedDateTime.now()
2022-07-15T11:33:28.648-04:00[America/New_York]

问题是,如何将表数据读入ZonedDateTime进行苹果与苹果的比较。例如,一些神奇的方法,比如

ZonedDateTime.fromOffset(5).fromDst(false).asTz('UTC')

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-07-15 16:26:19

您可以在指定的偏移量中使用ZoneOffset,DST /false在这里似乎不相关。假设时间戳是本地的(而不是UTC),您可以这样做:

代码语言:javascript
复制
public static void main(String[] args) {
    record TimestampAndOffset(String timestamp, int offsetHours) { }
    
    var timeData = List.of(
            new TimestampAndOffset("2022-07-15T13:32:00", 5),
            new TimestampAndOffset("2022-01-15T13:32:00", 5),
            new TimestampAndOffset("2022-07-15T13:32:00", 7));

    timeData.forEach(to -> {
        LocalDateTime localTimestamp = LocalDateTime.parse(to.timestamp());
        var zoneOffset = ZoneOffset.ofHours(to.offsetHours());
        var zonedValue = ZonedDateTime.of(localTimestamp, zoneOffset);
        System.out.println(zonedValue);
        System.out.println(zonedValue.withZoneSameInstant(ZoneOffset.UTC));
    });
}

为了简化本例的解析,我使用了以T为分隔符的ISO-8601格式。

输出:

代码语言:javascript
复制
2022-07-15T13:32+05:00
2022-07-15T08:32Z
2022-01-15T13:32+05:00
2022-01-15T08:32Z
2022-07-15T13:32+07:00
2022-07-15T06:32Z

正如user16320675在评论中指出的那样,重要的警告是,重复检查您的偏移量的含义,因为根据您问题的原版,您的数据可能使用逆偏移量(例如5而不是-5),在这种情况下,您需要使用ZoneOffset.ofHours(-to.offsetHours())代替。

正如Bourque在注释中提到的,请考虑使用OffsetDateTime是否对您的用例更有意义。

票数 3
EN

Stack Overflow用户

发布于 2022-07-15 22:19:30

@马克·罗特韦尔回答了这个问题。我不得不稍微修改他的答案,以适应我的确切需求和在Java 8上的限制,所以我现在发布我的确切解决方案,以防有用。

代码语言:javascript
复制
LocalDateTime localDt = LocalDateTime.parse("2022-07-15T13:32:00");
// IF DST MAKE THIS 4
ZoneOffset offset = ZoneOffset.ofHours(-5);
OffsetDateTime offsetDt = localDt.atOffset(offset);

// Not sure the canonical way to do a duration check but this seems to work
// Duration d = Duration.between( offsetDt , Instant.now());
Instant now = Instant.now();
boolean isFutureDate = offsetDt.toInstant().getEpochSecond() > now.getEpochSecond();
log.info("Original: {}, OffsetDt:{}, Now: {}, isFutureDate: {}" , localDt, offsetDt, now, isFutureDate);

哪种输出

代码语言:javascript
复制
Original: 2022-07-15T13:32, OffsetDt:2022-07-15T13:32-05:00, Now: 2022-07-18T16:28:48.384Z, isFutureDate: false
票数 2
EN

Stack Overflow用户

发布于 2022-07-16 01:02:12

tl;dr

你说过:

我的最终目标是将这些历史日期与当前时间进行比较,并得到它们之间的时间差。

代码语言:javascript
复制
record History( String dt , int offset , boolean dst ) { }
Instant now = Instant.now();
List.of(
                new History( "2022-07-15 13:32:00" , 5 , false ) ,
                new History( "2022-01-15 13:32:00" , 5 , true ) ,
                new History( "2022-07-15 13:32:00" , 7 , false )
        )
        .forEach(
                history -> System.out.println(
                        Duration.between(
                                LocalDateTime
                                        .parse( 
                                                history.dt().replace( " " , "T" ) 
                                        )
                                        .atOffset(
                                                ZoneOffset.ofHours( history.offset() )
                                        )
                                        .toInstant() ,
                                now
                        )
                )
        );

PT17H4M40.423919S PT4361H4M40.423919S PT19H4M40.423919S

OffsetDateTime

另外两个答案-- 马克·罗特韦尔亚当·休斯 --基本上都是正确的。但是,就像问题一样,他们使用的是ZonedDateTime,而不是更合适的类OffsetDateTime。而且它们没有解决问题中提出的具体解析需求。显然,输入数据已经存在于对象中,所以我将将其表示为记录

代码语言:javascript
复制
public record History( String dt , int offset , boolean dst ) { }

填充一些数据。

代码语言:javascript
复制
List < History > historyList =
        List.of(
                new History( "2022-07-15 13:32:00" , 5 , false ) ,
                new History( "2022-01-15 13:32:00" , 5 , true ) ,
                new History( "2022-07-15 13:32:00" , 7 , false )
        );

我们需要为每个输入生成一个java.time.OffsetDateTime对象。我们可以向记录中添加一个方法来执行该工作。

要解析给定的输入,我们可以定义一个格式模式匹配的DateTimeFormatter,也可以执行字符串操作,使输入符合OffsetDateTime.parse中默认使用的ISO 8601标准格式。我选择后者。我们只需要用一个T替换中间的空间。

正如罗特韦尔在他的回答中提到的那样,夏时制(DST)是否有效的布尔值与此无关。我们忽略History记录中的成员字段。

代码语言:javascript
复制
public record History( String dt , int offset , boolean dst )
{
    OffsetDateTime toOffsetDateTime ( )
    {
        LocalDateTime ldt = LocalDateTime.parse( this.dt.replace( " " , "T" ) );
        ZoneOffset o = ZoneOffset.ofHours( this.offset );
        OffsetDateTime odt = ldt.atOffset( o );
        return odt;
    }
}

捕捉当前的时刻。

代码语言:javascript
复制
Instant now = Instant.now() ;

您的目标是确定经过的时间。为此请使用Duration。为此,我们可以向History记录添加另一个方法。

代码语言:javascript
复制
package work.basil.example.history;

import java.time.*;

public record History( String dt , int offset , boolean dst )
{
    OffsetDateTime toOffsetDateTime ( )
    {
        LocalDateTime ldt = LocalDateTime.parse( this.dt.replace( " " , "T" ) );
        ZoneOffset o = ZoneOffset.ofHours( this.offset );
        OffsetDateTime odt = ldt.atOffset( o );
        return odt;
    }

    Duration elapsed ( final Instant instant )
    {
        Duration d = Duration.between( this.toOffsetDateTime().toInstant() , instant );
        return d;
    }
}

循环输入以报告它们经过的时间。

代码语言:javascript
复制
Instant now = Instant.now();
for ( History history : historyList )
{
    String message = history.elapsed( now ).toString() + " from " + history.toString() + " to " + now.toString();
    System.out.println( message );
}

跑的时候。

代码语言:javascript
复制
PT16H27M40.119075S from History[dt=2022-07-15 13:32:00, offset=5, dst=false] to 2022-07-16T00:59:40.119075Z
PT4360H27M40.119075S from History[dt=2022-01-15 13:32:00, offset=5, dst=true] to 2022-07-16T00:59:40.119075Z
PT18H27M40.119075S from History[dt=2022-07-15 13:32:00, offset=7, dst=false] to 2022-07-16T00:59:40.119075Z
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72996432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档