SimpleDateFormat(“yyyy-MM-dd'T'HH:mm:ssZ”);自定义时区

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); customize the timezone

提问人:monotor 提问时间:8/2/2023 最后编辑:Mark Rotteveelmonotor 更新时间:8/3/2023 访问量:175

问:

我想打印日期,字符在时区中间, 例:":"

2023-08-02T14:19:10+02:00

目前我正在使用这种模式:

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

它打印:

2023-08-02T14:19:10+0200

有什么想法吗?

下面是一个代码示例:

public class testDate {

    public static final DateFormat PATTERN = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

    public static String calendarToString(final Calendar dateToConvert, final DateFormat df) {
        return df.format(dateToConvert.getTime());
    }

    public static void main(String[] args) {
        Calendar effectiveDate = Calendar.getInstance();
        System.out.println(calendarToString(effectiveDate, PATTERN));
    }
}
Java 日期 simpledateformat 格式化程序

评论

4赞 Jens 8/2/2023
停止使用过时的类,例如 .迁移到较新的 APISimpleDateFormatjava.time
0赞 Jens 8/2/2023
请分享一个最小的可重复示例
1赞 Basil Bourque 8/3/2023
您预计在哪个时区出现 +02:00 的偏移量?
0赞 Anonymous 8/3/2023
我强烈建议您不要使用 和 。这些类设计得很差,使用起来很麻烦,而且很麻烦。幸运的是,它们早已过时。使用 java.time 中的其他类,现代 Java 日期和时间 API,使工作更轻松,减少不愉快的意外。请参阅Basil Bourque的好答案DateFormatSimpleDateFormatCalendarOffsetDateTime

答:

4赞 Mark Rotteveel 8/2/2023 #1

您需要使用 instead to 获取格式为 的时区。也就是说,您真的应该切换到使用新类型,并停止使用 .XXXZ{Z|{+|-}HH:mm}java.timeSimpleDateFormat

这在 SimpleDateFormat 文档中的一个示例中显示:

日期和时间模式 结果
... ...
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
2赞 Mr. Polywhirl 8/2/2023 #2

如果您使用的是 Java 1.8+,则应使用包中的类。java.time

用于类的格式也应适用于类。java.text.SimpleDateFormatjava.time.format.DateTimeFormatter

下面是一个示例:

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class ZonedDateTimeFormatExample {
  public static void main(String... args) {
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Africa/Cairo"));
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    System.out.printf("Current date and time in Cairo, Egypt: %s%n", fmt.format(now));
  }
}

避免使用 and 包进行日期/时间/日历解析和格式设置。java.textjava.util

这包括但不限于:

  • java.util.Calendar
  • java.util.Date
  • java.text.SimpleDateFormat

请查看:Java SE 8 日期和时间

1赞 Basil Bourque 8/3/2023 #3

TL的;博士

  • 你工作太辛苦了。
  • 使用现代 java.time。切勿使用 & .CalendarSimpleDateFormat
  • 无需为标准格式指定格式模式。
  • 截断不需要的小数秒。
OffsetDateTime.now().truncatedTo( SECONDS ).toString()

2023-08-02T14:19:10+02:00

java.time.OffsetDateTime

您正在使用糟糕的日期时间类,这些类在几年前被 JSR 310 中定义的现代 java.time 类所取代。

对于在 UTC 偏移量上下文中具有时间的日期,请使用类 OffsetDateTime

首先指定所需的偏移量

ZoneOffset offset = ZoneOffset.ofHours( 2 ) ;  // +02:00

捕获该偏移量中显示的当前时刻

OffsetDateTime odt = OffsetDateTime.now( offset ) ;

由于您对小数秒不感兴趣,因此请截断

OffsetDateTime odt = odt.truncatedTo( ChronoUnit.SECONDS ) ;

以您想要的格式生成文本,该格式恰好符合 java.time 在生成/解析文本时默认使用的 ISO 8601 标准格式。因此,无需指定格式模式。

String output = odt.toString() ;

2023-08-02T14:19:10+02:00

您可能希望指定一个时区以自动确定该时间点生效的偏移量,而不是对偏移量进行硬编码。

String output = 
    ZonedDateTime
    .now(
        ZoneId.of( "Africa/Gaborone" ) 
    )
    .toOffsetDateTime()
    .truncatedTo( ChronoUnit.SECONDS )
    .toString()
;

评论

1赞 Anonymous 8/3/2023
好而知识渊博的答案。 方便地接受 a(而不仅仅是 a)。因此,在上一个代码段中,您可以有利地使用 ,并且不需要转换。OffsetDateTime.now()ZoneIdZoneOffsetOffsetDateTime.now( ZoneId.of( "Africa/Gaborone" ) )
0赞 Basil Bourque 8/4/2023
@OleV.V.你的是一个聪明的解决方案。但我可能更喜欢更长的解决方案,中间人可以明确我的意图。但这实际上是一个有争议的问题,因为我无法想象我宁愿有一个而不是一个作为最终结果的情况。ZonedDateTimeOffsetDateTimeZonedDateTime
0赞 Anonymous 8/4/2023
右。在大多数实际程序中,我们不会满足于字符串,而是需要 date-time 对象,然后当我们将其作为某个时区的当前时间时,它是最合适的类型。第三种选择是截断并使用 .更喜欢哪个取决于情况(和口味)。ZonedDateTimeZonedDateTimeDateTimeFormatter.ISO_OFFSET_DATE_TIME