Java LocalDateTime 格式问题
Java LocalDateTime formatting issue
我制作了一个名为 Observation
的 class,其构造函数将 CSV 文件的单行作为输入。我已经提取了 LocalDateTime
,但是,它没有按照我的预期进行格式化。
public class Observation {
private String date, time, datetimeStr;
private LocalDateTime dateTime;
private static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm");
public Observation(String line) {
String[] parts = line.trim().split(",");
if (parts.length != 14) {
throw new InputMismatchException("Error: Invalid data!");
}
date = String.valueOf(parts[6]);
time = String.valueOf(parts[7]);
dateTimeStr = date + " " + time;
dateTime = LocalDateTime.parse(dateTimeStr, FORMAT);
}
// DateTime Getter
public LocalDateTime getDateTime() {
return dateTime;
}
public static void main(String[] args) {
String input= "Leeds,Albion Street North,2017,March,13,Saturday,01-Apr-17,00:00,197,0,197,197,0,197";
Observation test = new Observation(input);
// Print out DateTime
System.out.println("Date-Time: " + test.getDateTime());
}
}
所以我想要的格式是 "01-Apr-17 00:00"
并且我正在使用上面指定的格式化程序 "dd-MMM-yy HH:mm"
。
使用 dateTime getter 时,我从终端获得的结果是:
Ashs-MacBook-Pro:resit asheastham$ Java ObservationTest
Date-Time: 2017-04-01T00:00
与您的假设相反,LocalDateTime.parse(dateTimeStr, FORMAT) does not parse _and format_ the contents of
dateTimeStr` 但仅解析日期时间值,期望它具有您在 FORMAT 中指定的格式。
输出时需要格式化日期时间值:
public static void main(String[] args) {
String input= "Leeds,Albion Street North,2017,March,13,Saturday,01-Apr-17,00:00,197,0,197,197,0,197";
Observation test = new Observation(input);
// Print out DateTime
System.out.println("Date-Time: " + FORMAT.format(test.getDateTime()));
}
这会生成所需的输出:
Date-Time: 01-Apr-17 00:00
我认为您在日期方面混淆了 2 个不同的 "concepts":日期对象的 value 和 此值以某种特定格式表示。
一个LocalDateTime
对象代表一个date/time:它保存着日、月、年、时、分、秒和纳秒的值。但是日期本身 has no format at all - 这个 link 是关于 java.util.Date
,但是日期没有格式的一般概念也适用于 LocalDateTime
。
LocalDateTime
对象只有与日期和时间相对应的值,但是这些值可以以多种不同的方式显示。而那些不同的方式与价值观本身无关。因此,date/time April 1st 2017 at midnight 可以是 represented/displayed 许多不同的 格式:
- 4 月 1 日st 2017 00:00:00
- 2017 年 1 月 4 日 0:00
- 2017 年 4 月 1 日 00:00
- 2017-04-01T00:00
- 还有许多其他人...
虽然以上所有格式都不同,它们代表相同的日期和时间。各个字段(日、月、年、时、秒等)的值相同,因此都表示相同的date/time值(在本例中,相同 LocalDateTime
).
当您执行 LocalDateTime.parse(dateTimeStr, FORMAT)
时,您正在将特定的 格式 转换为日期值(在本例中为 LocalDateTime
)。这个操作叫做parsing:得到一个String
(一个文本)在一个特定的格式并且把它转换成date/time 值.
创建的DateTimeFormatter
指定格式是什么:
FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm")
这意味着要解析的 String
将采用指定的格式 - 在这种情况下,dd
(2 位数字的日期),然后是 -
,然后是MMM
(月份简称)等。 javadoc 包含有关所有可用模式的详细信息。
当你这样做时:
System.out.println("Date-Time: " + test.getDateTime());
此代码隐式调用 LocalDateTime
的 toString()
方法,此方法 returns the date/time in a specific format:
Outputs this date-time as a String, such as 2007-12-03T10:15:30.
The output will be one of the following ISO-8601 formats:
uuuu-MM-dd'T'HH:mm
uuuu-MM-dd'T'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss.SSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS
The format used will be the shortest that outputs the full value of the time where the omitted parts are implied to be zero
这就是为什么您的程序将日期输出为 2017-04-01T00:00
的原因:这是 LocalDateTime::toString()
方法的结果。
如果您想以 01-Apr-17 00:00
格式打印 LocalDateTime
,您应该调用 FORMAT.format(test.getDateTime())
(已在 中解释)。
如果您同时需要 LocalDateTime
(存储它,)和指定格式的日期,并且在构造函数中执行所有操作,则必须保留 2 个不同的字段(一个 LocalDateTime
和一个 String
).
实际上,您已经在这样做了。您的 dateTimeStr
字段已包含所需格式的日期,因此只需为其创建一个 getter。或者创建另一个方法(如 getFormattedDateTime()
),即 returns FORMAT.format(this.dateTime)
。然后你将有 2 种方法:一种是 returns LocalDateTime
(当你需要日期对象时,比如存储它时),另一种是 returns 格式化的 String
(当你需要打印它时)。
还有一件事:月份名称 ("Apr") 是英文的。您的代码可以正常工作,因为 JVM 的默认语言环境也是英语,但不能保证它总是那样。并且默认区域设置可以在不通知的情况下更改,即使在运行时也是如此(同一 JVM 中的其他一些应用程序可以调用 Locale.setDefault()
,或者有人可能错误配置 JVM,您的代码将突然中断)。
为避免这种情况,您可以使用 java.util.Locale
设置格式化程序并明确表示您使用的是英语:
// formatter always uses English for month names
DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm", Locale.ENGLISH);
我制作了一个名为 Observation
的 class,其构造函数将 CSV 文件的单行作为输入。我已经提取了 LocalDateTime
,但是,它没有按照我的预期进行格式化。
public class Observation {
private String date, time, datetimeStr;
private LocalDateTime dateTime;
private static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm");
public Observation(String line) {
String[] parts = line.trim().split(",");
if (parts.length != 14) {
throw new InputMismatchException("Error: Invalid data!");
}
date = String.valueOf(parts[6]);
time = String.valueOf(parts[7]);
dateTimeStr = date + " " + time;
dateTime = LocalDateTime.parse(dateTimeStr, FORMAT);
}
// DateTime Getter
public LocalDateTime getDateTime() {
return dateTime;
}
public static void main(String[] args) {
String input= "Leeds,Albion Street North,2017,March,13,Saturday,01-Apr-17,00:00,197,0,197,197,0,197";
Observation test = new Observation(input);
// Print out DateTime
System.out.println("Date-Time: " + test.getDateTime());
}
}
所以我想要的格式是 "01-Apr-17 00:00"
并且我正在使用上面指定的格式化程序 "dd-MMM-yy HH:mm"
。
使用 dateTime getter 时,我从终端获得的结果是:
Ashs-MacBook-Pro:resit asheastham$ Java ObservationTest
Date-Time: 2017-04-01T00:00
与您的假设相反,LocalDateTime.parse(dateTimeStr, FORMAT) does not parse _and format_ the contents of
dateTimeStr` 但仅解析日期时间值,期望它具有您在 FORMAT 中指定的格式。
输出时需要格式化日期时间值:
public static void main(String[] args) {
String input= "Leeds,Albion Street North,2017,March,13,Saturday,01-Apr-17,00:00,197,0,197,197,0,197";
Observation test = new Observation(input);
// Print out DateTime
System.out.println("Date-Time: " + FORMAT.format(test.getDateTime()));
}
这会生成所需的输出:
Date-Time: 01-Apr-17 00:00
我认为您在日期方面混淆了 2 个不同的 "concepts":日期对象的 value 和 此值以某种特定格式表示。
一个LocalDateTime
对象代表一个date/time:它保存着日、月、年、时、分、秒和纳秒的值。但是日期本身 has no format at all - 这个 link 是关于 java.util.Date
,但是日期没有格式的一般概念也适用于 LocalDateTime
。
LocalDateTime
对象只有与日期和时间相对应的值,但是这些值可以以多种不同的方式显示。而那些不同的方式与价值观本身无关。因此,date/time April 1st 2017 at midnight 可以是 represented/displayed 许多不同的 格式:
- 4 月 1 日st 2017 00:00:00
- 2017 年 1 月 4 日 0:00
- 2017 年 4 月 1 日 00:00
- 2017-04-01T00:00
- 还有许多其他人...
虽然以上所有格式都不同,它们代表相同的日期和时间。各个字段(日、月、年、时、秒等)的值相同,因此都表示相同的date/time值(在本例中,相同 LocalDateTime
).
当您执行 LocalDateTime.parse(dateTimeStr, FORMAT)
时,您正在将特定的 格式 转换为日期值(在本例中为 LocalDateTime
)。这个操作叫做parsing:得到一个String
(一个文本)在一个特定的格式并且把它转换成date/time 值.
创建的DateTimeFormatter
指定格式是什么:
FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm")
这意味着要解析的 String
将采用指定的格式 - 在这种情况下,dd
(2 位数字的日期),然后是 -
,然后是MMM
(月份简称)等。 javadoc 包含有关所有可用模式的详细信息。
当你这样做时:
System.out.println("Date-Time: " + test.getDateTime());
此代码隐式调用 LocalDateTime
的 toString()
方法,此方法 returns the date/time in a specific format:
Outputs this date-time as a String, such as 2007-12-03T10:15:30. The output will be one of the following ISO-8601 formats:
uuuu-MM-dd'T'HH:mm
uuuu-MM-dd'T'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss.SSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSThe format used will be the shortest that outputs the full value of the time where the omitted parts are implied to be zero
这就是为什么您的程序将日期输出为 2017-04-01T00:00
的原因:这是 LocalDateTime::toString()
方法的结果。
如果您想以 01-Apr-17 00:00
格式打印 LocalDateTime
,您应该调用 FORMAT.format(test.getDateTime())
(已在
如果您同时需要 LocalDateTime
(存储它,LocalDateTime
和一个 String
).
实际上,您已经在这样做了。您的 dateTimeStr
字段已包含所需格式的日期,因此只需为其创建一个 getter。或者创建另一个方法(如 getFormattedDateTime()
),即 returns FORMAT.format(this.dateTime)
。然后你将有 2 种方法:一种是 returns LocalDateTime
(当你需要日期对象时,比如存储它时),另一种是 returns 格式化的 String
(当你需要打印它时)。
还有一件事:月份名称 ("Apr") 是英文的。您的代码可以正常工作,因为 JVM 的默认语言环境也是英语,但不能保证它总是那样。并且默认区域设置可以在不通知的情况下更改,即使在运行时也是如此(同一 JVM 中的其他一些应用程序可以调用 Locale.setDefault()
,或者有人可能错误配置 JVM,您的代码将突然中断)。
为避免这种情况,您可以使用 java.util.Locale
设置格式化程序并明确表示您使用的是英语:
// formatter always uses English for month names
DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("dd-MMM-yy HH:mm", Locale.ENGLISH);