首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重复事件日期处理冬季时间/夏季时间

重复事件日期处理冬季时间/夏季时间
EN

Stack Overflow用户
提问于 2017-10-27 10:53:34
回答 2查看 1.1K关注 0票数 1

在我的应用程序中,用户可以创建重复事件,例如“每个星期六中午12点午餐”。

现在我遇到了一个问题,我不知道如何正确处理。如果事件链很大,并且具有不同的时区(冬季和夏季时间),则列出所有这些事件显示不同的时间。

例如,存储服务器端的日期如下:

代码语言:javascript
运行
复制
2017-10-28T12:00:00.000+02:00

因此,当列出事件客户端时,它可以如下所示:

代码语言:javascript
运行
复制
2017-10-21 12:00:00.000 (parsed from: 2017-10-21T12:00:00.000+02:00)
2017-10-28 12:00:00.000 (parsed from: 2017-10-28T12:00:00.000+02:00)
2017-11-04 11:00:00.000 (parsed from: 2017-11-04T12:00:00.000+02:00)
2017-11-11 11:00:00.000 (parsed from: 2017-11-11T12:00:00.000+02:00)

在第二次和第三次之间,客户更改为冬季时间和+01:00。时间会相应地调整,用户可能会认为事件会突然开始,而且会提前一小时,即使它是在同一时间开始的。

我希望它在客户端解析时总是显示事件时间(12:00),而不管时区如何。另一种解决方案是,如果该信息可以用Joda时间提取,则说明在夏季/冬季时间显示的信息。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-27 11:03:48

如果您想要的话,我会使用java8 LocalDateTime类服务器端,忽略时区。

LocalDateTime完全是为了处理不需要时区信息而声明日期(和时间)的情况。

如果数据库不支持存储时区少的日期时间,则每次都可以使用相同的时区(例如UTC)将其转换为服务器上的时间戳。只需确保将其发送到客户端,并将其作为LocalDateTime从客户端接收。

编辑:为了响应下面的注释,如果要根据用户的本地时区向用户显示日期,最好将ZonedDateTime存储在标准时区(例如,UTC),并存储用户的现场。然后,您可以使用区域设置将日期转换为特定于用户的日期格式,这将使DST和其他时区更改牢记在心。

EDIT2:对于转换日期时间,您可以使用区域ZoneId。区域设置对于格式化仍然很有用。

票数 2
EN

Stack Overflow用户

发布于 2018-05-23 02:55:01

java.time

Buurman的答复几乎是正确的,但并不完全正确。

Joda-Time项目确实处于维护模式,其创建者建议迁移到Java8及更高版本中的java.time类。Joda-Time和java.time JSR 310都是由同一个人,Stephen领导的.因此,迁移是相当容易的,因为许多核心思想是相同的。

如果你试图代表“每周六中午的午餐”,你就无法可靠地存储未来的确切时刻。世界各地的政治家都表现出重新定义时区的倾向。他们这样做的次数令人惊讶,而且通常是在很少有警告的情况下这样做的。所以,你不可能知道“中午”是什么时候,从一天中的时间来看。时钟定义的变化意味着你在追逐一个移动的目标。

因此,“每周六中午的午餐”需要跟踪一周的一天和一天的时间。Java有两个类。

代码语言:javascript
运行
复制
DayOfWeek dayOfWeek = DayOfWeek.SATURDAY ;  // Enum with seven predefined objects, Monday-Saturday.

LocalTime localTime = LocalTime.of( 12 , 0 ) ;  // Noon.

当您说“中午”时,您还需要存储预定的时区。每一天,印度的中午时间都比法国早得多,魁北克的午休时间甚至更晚。因此,一天中的时间只有在特定时区的上下文中才有意义。

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

代码语言:javascript
运行
复制
ZoneId zoneId = ZoneId.of( "America/Montreal" ) ;

您可以投影出一系列这些午餐,确定每个午餐的确切时刻(时间线上的点)。但你只能暂时这么做。鉴于各国政府已经证明,它们愿意重新定义时区的抵消值,只需几个月、几周、天数甚至小时数的预警,你就无法储存这些预测。在运行时动态地计算它们。

今天就决定。这当然需要一个时区。在任何特定时刻,全球各地的日期因地区而异。

代码语言:javascript
运行
复制
LocalDate today = LocalDate.now( zoneId ) ;

下个星期六去,如果已经是星期六,就呆在今天。

代码语言:javascript
运行
复制
LocalDate firstSaturday = today.with( TemporalAdjusters.nextOrSame( dayOfWeek ) ) ;

确定该日期该区域正午时间线上的点。

代码语言:javascript
运行
复制
ZonedDateTime firstLunch = ZonedDateTime.of( firstSaturday , localTime , zoneId ) ;

您可以通过提取Instant来查看与UTC相同的时刻。

代码语言:javascript
运行
复制
Instant firstLunchInstant = firstLunch.toInstant() ;

您可以通过在LocalDate中添加一个星期,并重复上面的步骤,在下一个日期要求中午,来继续这个预测。如果这一天的时间恰好在该区域的该日期无效(例如夏时制时间“Spring- adjusts”切入),则ZonedDateTime类将相应地进行调整。请务必阅读文档以了解其调整算法。

代码语言:javascript
运行
复制
int weeksToProject = 10 ;  // Run out 10 weeks.
List< ZonedDateTime > lunches = new ArrayList<>( weeksToProject ) ;
LocalDate localDate = firstSaturday ;
for( int i = 0 ; i < 10 ; i ++ ) {
    localDate = localDate.plusWeeks( i ) ;
    ZonedDateTime zdt = ZonedDateTime.of( localDate , localTime , zoneId ) ;  
    lunches.add( zdt ) ;
}

数据库

至于将“每周六中午午餐”存储在数据库中:

  • 一天中的时间可以存储在SQL-标准类型TIME WITHOUT TIME ZONE类型中. myPreparedStatement.setObject( … , localTime ) ; LocalTime localTime = myResultSet.getObject( … , LocalTime.class ) ;
  • 星期一天可以使用英文硬编码的DayOfWeek枚举值名称(如MONDAY )存储在VARCHAR中。或者,您可以将每周的天数存储为整数。对于一个数字,我强烈建议周一至周日使用ISO 8601标准1-7。一定要清楚地记录你的号码对后代的意义。
  • 时区可以作为文本存储在格式化中的VARCHAR中。

ZonedDateTime对象应该是暂时的,根据需要动态创建。所以你不会把它们储存起来。

关于java.time

http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。

在哪里获得java.time类?

  • Java 8Java 9Java 10,以及后来的
    • 内置的。
    • 带有捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • java.time的大部分功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

  • 安卓
    • 较晚版本的Android实现的java.time类。
    • 对于早期的Android (<26),https://github.com/JakeWharton/ThreeTenABP项目采用了http://www.threeten.org/threetenbp/ (上面提到的)。见http://stackoverflow.com/q/38922754/642706

三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter更多

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46973401

复制
相关文章

相似问题

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