如何以数字格式获取当前日期和时区

时间:2017-06-05 07:14:48

标签: java android date timezone date-formatting

我想以这种格式打印当前日期2017/06/05> Year/Month/Day 并在其旁边,以此格式+3

的当前时区

我使用了这段代码

String DateToday  = DateFormat.getDateInstance().format(new Date());
String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName();
txt.setText(DateToday + " | "+ TZtoday );

但是,它显示如下:

  

2017年6月5日|阿拉伯标准时间

我想这样:

  

2017/06/05 | 3

4 个答案:

答案 0 :(得分:3)

我知道您使用的是Android,而且我知道Android内置的功能是长期过时的类,例如SimpleDateFormatDateCalendar和{{1} }。我仍然说,如果你正在做日期和/或时间和/或时区的事情,你应该认真考虑跳过这些课程并继续他们现代的替代品。这将要求您获得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

亚洲/加德满都时区的结果可能不完全符合您的要求:

2017/06/05 | +545

您可能认为我的代码段与使用旧类相比并不是非常有利。当我说很多情况下旧课程会给你带来负面的惊喜时,你可以接受我的意思,所以你越早开始使用新课程就越好。或者,您可能会在格式模式字符串中输入拼写错误,并注意如何使用旧类获得令人惊讶的结果而没有任何错误的迹象,而较新的类将尝试将有意义的错误消息组合在一起。 / p>

需要注意的另一个细节是我只读取系统时钟和JVM的时区一次(将时区传递回now()以确保它用于时间)。您在问题中的代码首先格式化日期,然后读取时区。如果有人更改了两者之间的时区,结果将不一致。这不太可能,但这也意味着任何人都不可能弄清楚发生了什么。

正则表达式中的(?<=\\+|-)是一个后视:我用空字符串替换0+之前的-。我徒劳地搜索了一种格式化区域偏移的方法,如+3所示,所以我采用了replaceFirst方法。

更多链接:How to use ThreeTenABP in Android Project

答案 1 :(得分:2)

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", "$1"); // = +3
System.out.println(sdf.format(new Date()) + " | " + tz);

给出:

2017/06/05 | +3

答案 2 :(得分:1)

只是补充@Ole V.V.'s answer,我发现了另一种使用ThreeTenABP的方式,但不需要替换正则表达式(尽管我不认为它很多更简单,更多在下面)。

使用DateTimeFormatterBuilder,您可以使用HashMap将偏移值映射到String。因此,对于整个偏移小时数(如+03:00),您可以将相应的值映射到字符串+3,依此类推。

唯一的问题是ZoneOffset具有精度。最小值和最大值分别为UTC-18:00:00UTC+18:00:00。因此,所有可能的值都是UTC-18:00:00UTC-17:59:59UTC-17:59:58等等。格式化程序要求映射所有可能的值(否则它将显示偏移量的秒值),因此映射将有超过120K的条目!

为了制作这张地图,我制作了2个循环:

  • 第一个循环将整个小时偏移(+01:00映射到+1-02:00映射到-2等等)
  • 第二个循环映射所有其他值(它们保持不变):
    • 整个小时&gt; = 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条目的地图是否比使用正则表达式更好(由您决定)。这种方法创建了一个大的地图,但至少不需要输出后处理(不确定这是否是一个合理的权衡)
  • 如果您希望将整小时偏移&gt; = 10显示为+10+11等,只需将第一个for循环更改为for (int i = 1; i <= maxOffsetYouWant; i++) - 只是提醒maximum possible value for maxOffsetYouWant is 18

答案 3 :(得分:0)

使用以下逻辑来获得所需的日期格式。

    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


    }