- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图根据 ISO-8601 日期格式字符串输入计算一年中的星期几。最初我尝试使用 java.time.ZonedDateTime 进行此操作,但它为输入日期 - 2-Jan-2049 提供了不正确的结果。然后我尝试使用 Calendar API,它也给出了 2049 年 12 月 31 日的错误响应。
我附上了示例测试代码
public class ZonedDateTimeTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("======================================");
String instantStr1 = "2049-01-02T03:48:00Z";
printYearAndWeekOfYear(instantStr1);
System.out.println("======================================");
String instantStr2 = "2049-12-31T03:48:00Z";
printYearAndWeekOfYear(instantStr2);
System.out.println("======================================");
}
public static void printYearAndWeekOfYear(String ISODate) {
System.out.println("Date provided -> " + ISODate);
ZonedDateTime utcTimestamp = parseToInstant(ISODate).atZone(ZoneOffset.UTC);
int year = utcTimestamp.getYear();
int weekOfYear = utcTimestamp.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
System.out.println("Using ZonedDateTime API:: Year " + year + " weekOfYear " + weekOfYear);
Date d1 = Date.from(parseToInstant(ISODate));
Calendar cl = Calendar.getInstance();
cl.setTime(d1);
int year1 = cl.get(Calendar.YEAR);
int weekOfYear1 = cl.get(Calendar.WEEK_OF_YEAR);
System.out.println("Using Calendar API:: Year " + year1 + " weekOfYear " + weekOfYear1);
}
public static Instant parseToInstant(String ISODate) {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(ISODate, Instant::from);
}
}
上面代码的输出
======================================
Date provided 2049-01-02T03:48:00Z
Using ZonedDateTime API: Year 2049 weekOfYear 53
Using Calendar API: Year 2049 weekOfYear 1
======================================
Date provided 2049-12-31T03:48:00Z
Using ZonedDateTime API: Year 2049 weekOfYear 52
Using Calendar API: Year 2049 weekOfYear 1
======================================
最佳答案
一开始您的代码有四个问题:
Calendar
时,您使用的是系统默认时区,这很可能会改变 Instant
所在的日期。如果您将日历设置为使用 UTC,您将使其更加一致。Calendar.YEAR
,它将为您提供日历 年而不是周 年。您需要改用 Calendar.getWeekYear()
。ZonedDateTime.getYear()
,这又是日历年。你应该使用 utcTimestamp.get(IsoFields.WEEK_BASED_YEAR)
Calendar.getInstance()
,它可能会为您提供一个非公历,或者它可能为您要执行的计算设置了不合适的星期几解决这些问题(和命名约定)我们最终得到:
import java.util.*;
import java.time.*;
import java.time.format.*;
import java.time.chrono.*;
import java.time.temporal.*;
public class ZonedDateTimeTest {
public static void main(String[] args) {
printYearAndWeekOfYear("2049-01-02T03:48:00Z");
String instantStr2 = "2049-12-31T03:48:00Z";
printYearAndWeekOfYear("2049-12-31T03:48:00Z");
}
public static void printYearAndWeekOfYear(String isoDate) {
System.out.println("Date provided -> " + isoDate);
Instant instant = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(isoDate, Instant::from);
ZonedDateTime utcTimestamp = instant.atZone(ZoneOffset.UTC);
int year = utcTimestamp.get(IsoFields.WEEK_BASED_YEAR);
int weekOfYear = utcTimestamp.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
System.out.println("ZonedDateTime: Year " + year + " weekOfYear " + weekOfYear);
// Force the Gregorian calendar with ISO rules and using UTC
Calendar calendar = new GregorianCalendar();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setMinimalDaysInFirstWeek(4);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(Date.from(instant));
int calYear = calendar.getWeekYear();
int calWeekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
System.out.println("Calendar: Year " + calYear + " weekOfYear " + calWeekOfYear);
System.out.println();
}
}
输出:
Date provided -> 2049-01-02T03:48:00Z
ZonedDateTime: Year 2048 weekOfYear 53
Calendar: Year 2048 weekOfYear 53
Date provided -> 2049-12-31T03:48:00Z
ZonedDateTime: Year 2049 weekOfYear 52
Calendar: Year 2049 weekOfYear 52
我觉得这两个都不错。
关于java - 使用 ZonedDateTime 和日历 API 计算年度周问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41673485/
我创建了两个 ZonedDateTime 对象,我认为它们应该相等: public static void main(String[] args) { ZoneId zid = ZoneId.
假设我有一个 ZonedDateTime: ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), ZoneI
给定以下单元测试: @Test public void zonedDateTimeCorrectlyRestoresItself() { // construct a new instance
我正在尝试将 ZonedDateTime 与以下代码进行比较: val now = ZonedDateTime.now() val query = for { x Timestamp.from(
我最近迁移到 Java 8,希望能更轻松地处理本地和分区时间。 但是,在我看来,在解析简单日期时,我遇到了一个简单的问题。 public static ZonedDateTime convertirA
您好,我已经搜索过类似的问题,但没有成功。我正在调用一个 ws,它将一个 token 发回给我,当它是有效的示例时: { "token": ..., "notBefore":"Thu 21
我有一个 ZonedDateTime 对象,我想根据给定的区域设置对其进行格式化。 IE。在美国,我希望格式为“M-dd-yy”,但在英国则应为“dd-M-yy”。 在给定的语言环境下执行此操作的最佳
在比较 ZonedDateTimes 时,使用 和 == 并不总是与使用 .isBefore、.isAfter 和 isEqual 相同,如下面的 Kotlin 示例所示: import java.
我有以下功能 public String getDateAndTimeInUserFormat(String value, DateTimeFormat inputFormat) { retu
我的时间以毫秒为单位,我需要将其转换为 ZonedDateTime 对象。 我有以下代码 long m = System.currentTimeMillis(); LocalDateTime d =
我尝试将字符串转换为 ZonedDateTime。这是我的代码: String startTime = "Wed Mar 21 2018 08:00:00 GMT 0330 (IRST)"; Stri
在比较 ZonedDateTimes 时,使用 和 == 并不总是与使用 .isBefore、.isAfter 和 isEqual 相同,如下面的 Kotlin 示例所示: import java.
我正在尝试获取存储为 UTC 的日期时间并将其转换为给定时区的日期时间。据我所知,ZonedDateTime 是正确的(“美国/芝加哥”比 UTC 晚 5 小时),但 DateTimeFormatte
我需要将字符串 2020-04-15T23:00:00+0000 转换为 ZonedDateTime。我尝试了以下方法,但没有成功: DateTimeFormatter formatter = Dat
如何将已设置的 ZonedDateTime 时间更改为“java.time.LocalTime.MIN”或“java.time.LocalTime.MAX”? ZonedDateTime date =
我正在尝试将字符串转换为 ZonedDateTime。 我尝试过以下操作: SimpleDateFormat zonedDateTimeFormat = new SimpleDateFormat("y
我目前正在研究日期在英国夏令时间之内和之外时的 ZonedDateTime 行为。 英国夏令时间从 3 月 25 日开始,增加一小时 (+1)。 我创建了几个 ZonedDateTime 实例(UTC
ZonedDateTime zdt3 = ZonedDateTime.parse("1999-09-09 09:09:09.999", DateTimeFormatter.of
我有一个返回年、月、日和小时的 DTO。因此将值从 DTO 传递到 ZonedDateTime.of 方法。此处,时间显示为太平洋标准时间上午 10 点。因此,尝试将其转换为 UTC。 当传递月份为
String ip="2011-05-01T06:47:35.422-05:00"; ZonedDateTime mzt = ZonedDateTime.parse(ip).toInstant().a
我是一名优秀的程序员,十分优秀!