If your DateTime
是 UTC 并且您想将其转换为另一个时区,您可以使用withZone
方法进行转换。
对于下面的示例,我的默认时区是America/Sao_Paulo
(你可以使用检查你的DateTimeZone.getDefault()
):
// create today's date in UTC
DateTime mStartDate = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay();
// date/time in UTC
System.out.println(mStartDate); // 2017-06-13T00:00:00.000Z
// date/time in my default timezone (America/Sao_Paulo)
System.out.println(mStartDate.withZone(DateTimeZone.getDefault())); // 2017-06-12T21:00:00.000-03:00
输出是:
2017-06-13T00:00:00.000Z
2017-06-12T21:00:00.000-03:00
请注意,withZone
方法正确地将日期和时间转换为我的时区(在America/Sao_Paulo
当前偏移量是UTC-03:00
),因此进行了相应调整。
如果您只想获取时间(小时/分钟/秒),您可以使用toLocalTime()
method:
System.out.println(mStartDate.withZone(DateTimeZone.getDefault()).toLocalTime()); // 21:00:00.000
输出是:
21:00:00.000
如果您想要其他格式(例如,不打印秒分数的 3 位数字),您可以使用DateTimeFormatter
。好处是你可以在格式化程序中设置时区,所以你不需要转换DateTime
:
// create formatter for hour/minute/second, set it with my default timezone
DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm:ss").withZone(DateTimeZone.getDefault());
System.out.println(fmt.print(mStartDate)); // 21:00:00
输出是:
21:00:00
要获得您的范围,您可以将上述方法之一与您的DateTime
's (mStartDate
and mEndDate
),并使用DateTimeFormatter
更改为您需要的任何格式。
PS:我认为你在使用时缺少什么getMillis()
两个日期时间(UTC 和默认时区)都代表同一个瞬间。您只是将这一时刻转换为当地时间,但毫秒是相同的(想想,现在,此时此刻,世界上的每个人都在同一时刻(相同的毫秒),但他们的当地时间可能不同取决于他们在哪里)。因此,在转换 UTC 时DateTime
到另一个时区,我们只是找到该时区的当地时间,它对应于相同的毫秒。
您可以使用以下命令检查这一点getMillis()
两个对象上的方法:
System.out.println(mStartDate.getMillis()); // 1497312000000
System.out.println(mStartDate.withZone(DateTimeZone.getDefault()).getMillis()); // 1497312000000
请注意,即使我将对象转换为另一个时区,毫秒仍保持不变(1497312000000
)。这是因为两者都代表同一时刻,我只是将它们移动到各自当地时间不同的另一个时区。
Java 新的日期/时间 API
Joda-Time 它已停产并被新的 API 取代,因此我不建议用它开始一个新项目。如果您的情况如此,您可以考虑使用新的日期/时间 API,但如果您有一个使用 Joda 的大型代码库或者现在不想迁移它,您可以考虑其余的答案。
无论如何,即使在乔达的网站 http://www.joda.org/joda-time它说:“请注意,Joda-Time 被认为是一个很大程度上“完成”的项目。没有计划进行重大增强。如果使用 Java SE 8,请迁移到 java.time (JSR-310)。”.*
如果您正在使用Java 8,考虑使用新的 java.time API https://docs.oracle.com/javase/tutorial/datetime/。更容易,与旧 API 相比,漏洞较少且不易出错 https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api。我不确定它是否已适用于所有 Android 版本(但请参阅下面的替代方案)。
如果您正在使用Java ,您可以使用三十向后移植 http://www.threeten.org/threetenbp/,Java 8 新日期/时间类的一个很好的向后移植。而对于Android,有一种方法可以使用它,通过三十ABP https://github.com/JakeWharton/ThreeTenABP(更多关于如何使用它here https://stackoverflow.com/a/38922755/7605325).
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是java.time
在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是org.threeten.bp
),但是类和方法names是相同的。
要获取当天开始时的当前日期(UTC),您可以执行以下操作:
// UTC's today at start of the day
ZonedDateTime utc = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC);
System.out.println(utc); // 2017-06-13T00:00Z
首先我做了LocalDate.now(ZoneOffset.UTC)
查找当前本地 UTC 日期。如果我只使用LocalDate.now()
,它将获取我的默认时区中的当前日期,这不是我们想要的(它可能与 UTC 不同,具体取决于您所在的位置和时间以及默认时区是什么)。
然后我用了atStartOfDay(ZoneOffset.UTC)
以 UTC 开始新的一天。我知道使用 UTC 两次听起来多余,但 API 允许我们在此方法中使用任何时区,并且 IMO 它明确说明了我们想要的时区(如果日期位于夏令时更改的时区,则一天的开始可能不是午夜 - 时区参数是为了保证设置正确的值)。
输出是:
2017-06-13T00:00Z
要转换为我的默认时区,我可以使用ZoneId.systemDefault()
,在我的例子中返回America/Sao_Paulo
。要转换它并仅获取当地时间部分,只需执行以下操作:
System.out.println(utc.withZoneSameInstant(ZoneId.systemDefault()).toLocalTime()); // 21:00
输出是:
21:00
如果你想改变它,你也可以使用格式化程序:
// formatter for localtime (hour/minute/second)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(fmt.format(utc.withZoneSameInstant(ZoneId.systemDefault()))); // 21:00:00
输出是:
21:00:00