如何以数字格式获取当前日期和时区
How get the current date and the timezone in numbers format
我想以这种格式打印当前日期 2017/06/05
> Year/Month/Day
在它旁边,当前时区格式为 +3
我使用了这个代码
String DateToday = DateFormat.getDateInstance().format(new Date());
String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName();
txt.setText(DateToday + " | "+ TZtoday );
但是,显示是这样的:
Jun 5, 2017 | Arabia Standard Time
我想要这样:
2017/06/05 | +3
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd | X");
System.out.println(sdf.format(new Date()));
接近,但时区打印有前导零:
2017/06/05 | +03
我想你可以从时区中删除前导零,如果你需要:
SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat zone = new SimpleDateFormat("ZZZZZ"); // = +03:00
String tz = zone.format(new Date()).split(":")[0]
.replaceAll("^(\+|-)0", ""); // = +3
System.out.println(sdf.format(new Date()) + " | " + tz);
给出:
2017/06/05 | +3
使用以下逻辑获取所需的日期格式。
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(cal.getTime());
// Output "Wed Sep 26 14:23:28 EST 2012"
String formatted = format1.format(cal.getTime());
String formattedmain=formatted.replace("-","/");
System.out.println(formatted);
// Output "2012-09-26"
System.out.println(formattedmain);
//Output :- 2017/06/06
}
我知道你在 Android,我知道 Android 上内置的是早已过时的 类,例如 DateFormat
、SimpleDateFormat
、Date
和 Calendar
。我还是要说,如果你正在做一些日期 and/or 乘以 and/or 时区的事情,你应该认真考虑跳过这些 类 并继续使用它们的现代替代品。这将需要您获得 ThreeTenABP。那么我建议这样:
ZonedDateTime date = ZonedDateTime.now(ZoneId.systemDefault());
String tzToday = date.format(DateTimeFormatter.ofPattern("uuuu/MM/dd | x"));
tzToday = tzToday.replaceFirst("(?<=\+|-)0", "");
我电脑上的结果:
2017/06/05 | +2
Asia/Kathmandu 时区的结果可能不是您想要的:
2017/06/05 | +545
您可能认为我的代码片段与使用旧的 类 相比不是很有优势。你可能会相信我的话,在很多情况下旧的 类 会给你带来负面的惊喜,所以你越早开始使用新的越好。或者,例如,您可能在格式模式字符串中输入错误,并注意您如何使用旧的 类 获得令人惊讶的结果,没有任何迹象表明有任何错误,而较新的将尝试将有意义的组合在一起错误信息。
另一个需要注意的细节是我只读取一次系统时钟和 JVM 的时区(将时区传回 now()
以确保它用于时间)。您在问题中的代码首先格式化日期,然后读取时区。如果有人更改两者之间的时区,结果将不一致。不太可能,但这也意味着任何人都不太可能弄清楚发生了什么。
正则表达式中的 (?<=\+|-)
是一个回顾:我正在用空字符串替换前面有 +
或 -
的 0
。我徒劳地搜索了一种方法来格式化区域偏移量,如您所希望的 +3
,所以我求助于 replaceFirst
方法。
进一步link:.
只是补充 , I've found another way of doing it using ThreeTenABP,但不需要替换正则表达式(虽然我不认为它更简单,下面会详细介绍)。
使用 DateTimeFormatterBuilder
,您可以使用 HashMap
将偏移值映射到 String
。因此,对于整个偏移时间(如 +03:00
),您可以将相应的值映射到字符串 +3
等等。
唯一的问题是 ZoneOffset
的精度为 秒 。最小值和最大值分别为 UTC-18:00:00
和 UTC+18:00:00
。所以所有可能的值都是 UTC-18:00:00
、UTC-17:59:59
、UTC-17:59:58
等等。并且格式化程序要求映射所有可能的值(否则它会显示偏移量的秒值),因此映射将有超过 120K 个条目!
为了构建这张地图,我制作了 2 个循环:
- 第一个循环映射整个小时偏移量(
+01:00
到 +1
,-02:00
到 -2
等等)
- 第二个循环映射所有其他值(它们保持不变):
- 整小时 >= 10(如
+10:00
)
- 不是整小时(比如
+05:30
)
创建格式化程序的代码:
// builds a hashmap to map all offset values
Map<Long, String> map = new HashMap<>();
// First loop: Map whole hours from 1 to 9 and from -9 to -1
// So a "+01:00" offset is displayed as "+1"
for (int i = 1; i <= 9; i++) {
long seconds = ZoneOffset.ofHours(i).getTotalSeconds();
// 1 hour offset maps to "+1" and so on
map.put(seconds, "+" + i);
// -1 hour offset maps to "-1" and so on
map.put(-seconds, "-" + i);
}
// second loop: Need to map all other possible values for not-whole hours
// offsets like "+10:00" and "+01:30" are not changed
int minOffset = ZoneOffset.MIN.getTotalSeconds();
int maxOffset = ZoneOffset.MAX.getTotalSeconds();
for (long i = minOffset; i <= maxOffset; i++) {
// the map already contains whole hours, don't need to overwrite the values
if (!map.containsKey(i)) {
// uses default String representation (like "+05:30")
map.put(i, ZoneOffset.ofTotalSeconds((int) i).getId());
}
}
// create the formatter
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// year/month/day and the "|"
.appendPattern("uuuu/MM/dd | ")
// use the map of custom values (offset will use the values in the map)
.appendText(ChronoField.OFFSET_SECONDS, map)
// create formatter
.toFormatter();
一些测试:
LocalDateTime dt = LocalDateTime.of(2017, 5, 1, 10, 0);
ZonedDateTime z = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); // UTC-03:00
System.out.println(formatter.format(z)); // 2017/05/01 | -3
// just picking some timezone in Arabia Stardard Time
// (there are more than one timezone in AST: https://en.wikipedia.org/wiki/UTC%2B03:00#Arabia_Standard_Time)
// I don't know in which one you are
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Qatar")); // UTC+03:00
System.out.println(formatter.format(z)); // 2017/05/01 | +3
// 2-digit offset
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Vladivostok")); // UTC+10:00
System.out.println(formatter.format(z)); // 2017/05/01 | +10:00
// not whole hour
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Kathmandu")); // UTC+05:45
System.out.println(formatter.format(z)); // 2017/05/01 | +05:45
输出为:
2017/05/01 | -3
2017/05/01 | +3
2017/05/01 | +10:00
2017/05/01 | +05:45
备注:
- 我不知道有 120K 个条目的映射是否比使用正则表达式更好(由您决定)。这种方法创建了一个大地图,但至少不需要输出 post-processing(不确定这是否是一个合理的权衡)
- 如果你想整小时偏移>=10显示为
+10
,+11
等,只需将第一个for
循环更改为for (int i = 1; i <= maxOffsetYouWant; i++)
- 只是提醒 maximum possible value for maxOffsetYouWant
is 18.
我想以这种格式打印当前日期 2017/06/05
> Year/Month/Day
在它旁边,当前时区格式为 +3
我使用了这个代码
String DateToday = DateFormat.getDateInstance().format(new Date());
String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName();
txt.setText(DateToday + " | "+ TZtoday );
但是,显示是这样的:
Jun 5, 2017 | Arabia Standard Time
我想要这样:
2017/06/05 | +3
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd | X");
System.out.println(sdf.format(new Date()));
接近,但时区打印有前导零:
2017/06/05 | +03
我想你可以从时区中删除前导零,如果你需要:
SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat zone = new SimpleDateFormat("ZZZZZ"); // = +03:00
String tz = zone.format(new Date()).split(":")[0]
.replaceAll("^(\+|-)0", ""); // = +3
System.out.println(sdf.format(new Date()) + " | " + tz);
给出:
2017/06/05 | +3
使用以下逻辑获取所需的日期格式。
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(cal.getTime());
// Output "Wed Sep 26 14:23:28 EST 2012"
String formatted = format1.format(cal.getTime());
String formattedmain=formatted.replace("-","/");
System.out.println(formatted);
// Output "2012-09-26"
System.out.println(formattedmain);
//Output :- 2017/06/06
}
我知道你在 Android,我知道 Android 上内置的是早已过时的 类,例如 DateFormat
、SimpleDateFormat
、Date
和 Calendar
。我还是要说,如果你正在做一些日期 and/or 乘以 and/or 时区的事情,你应该认真考虑跳过这些 类 并继续使用它们的现代替代品。这将需要您获得 ThreeTenABP。那么我建议这样:
ZonedDateTime date = ZonedDateTime.now(ZoneId.systemDefault());
String tzToday = date.format(DateTimeFormatter.ofPattern("uuuu/MM/dd | x"));
tzToday = tzToday.replaceFirst("(?<=\+|-)0", "");
我电脑上的结果:
2017/06/05 | +2
Asia/Kathmandu 时区的结果可能不是您想要的:
2017/06/05 | +545
您可能认为我的代码片段与使用旧的 类 相比不是很有优势。你可能会相信我的话,在很多情况下旧的 类 会给你带来负面的惊喜,所以你越早开始使用新的越好。或者,例如,您可能在格式模式字符串中输入错误,并注意您如何使用旧的 类 获得令人惊讶的结果,没有任何迹象表明有任何错误,而较新的将尝试将有意义的组合在一起错误信息。
另一个需要注意的细节是我只读取一次系统时钟和 JVM 的时区(将时区传回 now()
以确保它用于时间)。您在问题中的代码首先格式化日期,然后读取时区。如果有人更改两者之间的时区,结果将不一致。不太可能,但这也意味着任何人都不太可能弄清楚发生了什么。
正则表达式中的 (?<=\+|-)
是一个回顾:我正在用空字符串替换前面有 +
或 -
的 0
。我徒劳地搜索了一种方法来格式化区域偏移量,如您所希望的 +3
,所以我求助于 replaceFirst
方法。
进一步link:
只是补充
使用 DateTimeFormatterBuilder
,您可以使用 HashMap
将偏移值映射到 String
。因此,对于整个偏移时间(如 +03:00
),您可以将相应的值映射到字符串 +3
等等。
唯一的问题是 ZoneOffset
的精度为 秒 。最小值和最大值分别为 UTC-18:00:00
和 UTC+18:00:00
。所以所有可能的值都是 UTC-18:00:00
、UTC-17:59:59
、UTC-17:59:58
等等。并且格式化程序要求映射所有可能的值(否则它会显示偏移量的秒值),因此映射将有超过 120K 个条目!
为了构建这张地图,我制作了 2 个循环:
- 第一个循环映射整个小时偏移量(
+01:00
到+1
,-02:00
到-2
等等) - 第二个循环映射所有其他值(它们保持不变):
- 整小时 >= 10(如
+10:00
) - 不是整小时(比如
+05:30
)
- 整小时 >= 10(如
创建格式化程序的代码:
// builds a hashmap to map all offset values
Map<Long, String> map = new HashMap<>();
// First loop: Map whole hours from 1 to 9 and from -9 to -1
// So a "+01:00" offset is displayed as "+1"
for (int i = 1; i <= 9; i++) {
long seconds = ZoneOffset.ofHours(i).getTotalSeconds();
// 1 hour offset maps to "+1" and so on
map.put(seconds, "+" + i);
// -1 hour offset maps to "-1" and so on
map.put(-seconds, "-" + i);
}
// second loop: Need to map all other possible values for not-whole hours
// offsets like "+10:00" and "+01:30" are not changed
int minOffset = ZoneOffset.MIN.getTotalSeconds();
int maxOffset = ZoneOffset.MAX.getTotalSeconds();
for (long i = minOffset; i <= maxOffset; i++) {
// the map already contains whole hours, don't need to overwrite the values
if (!map.containsKey(i)) {
// uses default String representation (like "+05:30")
map.put(i, ZoneOffset.ofTotalSeconds((int) i).getId());
}
}
// create the formatter
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// year/month/day and the "|"
.appendPattern("uuuu/MM/dd | ")
// use the map of custom values (offset will use the values in the map)
.appendText(ChronoField.OFFSET_SECONDS, map)
// create formatter
.toFormatter();
一些测试:
LocalDateTime dt = LocalDateTime.of(2017, 5, 1, 10, 0);
ZonedDateTime z = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); // UTC-03:00
System.out.println(formatter.format(z)); // 2017/05/01 | -3
// just picking some timezone in Arabia Stardard Time
// (there are more than one timezone in AST: https://en.wikipedia.org/wiki/UTC%2B03:00#Arabia_Standard_Time)
// I don't know in which one you are
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Qatar")); // UTC+03:00
System.out.println(formatter.format(z)); // 2017/05/01 | +3
// 2-digit offset
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Vladivostok")); // UTC+10:00
System.out.println(formatter.format(z)); // 2017/05/01 | +10:00
// not whole hour
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Kathmandu")); // UTC+05:45
System.out.println(formatter.format(z)); // 2017/05/01 | +05:45
输出为:
2017/05/01 | -3
2017/05/01 | +3
2017/05/01 | +10:00
2017/05/01 | +05:45
备注:
- 我不知道有 120K 个条目的映射是否比使用正则表达式更好(由您决定)。这种方法创建了一个大地图,但至少不需要输出 post-processing(不确定这是否是一个合理的权衡)
- 如果你想整小时偏移>=10显示为
+10
,+11
等,只需将第一个for
循环更改为for (int i = 1; i <= maxOffsetYouWant; i++)
- 只是提醒 maximum possible value formaxOffsetYouWant
is 18.