@@ -32,16 +32,40 @@ public final class DateUtils {
32
32
public static final LocalDate EPOCH = LocalDate .of (1970 , 1 , 1 );
33
33
public static final long DAY_IN_MILLIS = 60 * 60 * 24 * 1000L ;
34
34
35
- private static final DateTimeFormatter DATE_TIME_ESCAPED_LITERAL_FORMATTER_WHITESPACE = new DateTimeFormatterBuilder ()
35
+ private static final DateTimeFormatter DATE_TIME_FORMATTER_WHITESPACE = new DateTimeFormatterBuilder ()
36
36
.append (ISO_LOCAL_DATE )
37
37
.appendLiteral (' ' )
38
38
.append (ISO_LOCAL_TIME )
39
39
.toFormatter ().withZone (UTC );
40
- private static final DateTimeFormatter DATE_TIME_ESCAPED_LITERAL_FORMATTER_T_LITERAL = new DateTimeFormatterBuilder ()
40
+ private static final DateTimeFormatter DATE_TIME_FORMATTER_T_LITERAL = new DateTimeFormatterBuilder ()
41
41
.append (ISO_LOCAL_DATE )
42
42
.appendLiteral ('T' )
43
43
.append (ISO_LOCAL_TIME )
44
44
.toFormatter ().withZone (UTC );
45
+ private static final DateTimeFormatter DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE = new DateTimeFormatterBuilder ()
46
+ .append (ISO_LOCAL_DATE )
47
+ .optionalStart ()
48
+ .appendLiteral (' ' )
49
+ .append (ISO_LOCAL_TIME )
50
+ .toFormatter ().withZone (UTC );
51
+ private static final DateTimeFormatter DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL = new DateTimeFormatterBuilder ()
52
+ .append (ISO_LOCAL_DATE )
53
+ .optionalStart ()
54
+ .appendLiteral ('T' )
55
+ .append (ISO_LOCAL_TIME )
56
+ .toFormatter ().withZone (UTC );
57
+ private static final DateTimeFormatter ISO_LOCAL_DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE = new DateTimeFormatterBuilder ()
58
+ .append (DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE )
59
+ .optionalStart ()
60
+ .appendZoneOrOffsetId ()
61
+ .optionalEnd ()
62
+ .toFormatter ().withZone (UTC );
63
+ private static final DateTimeFormatter ISO_LOCAL_DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL = new DateTimeFormatterBuilder ()
64
+ .append (DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL )
65
+ .optionalStart ()
66
+ .appendZoneOrOffsetId ()
67
+ .optionalEnd ()
68
+ .toFormatter ().withZone (UTC );
45
69
46
70
private static final DateFormatter UTC_DATE_TIME_FORMATTER = DateFormatter .forPattern ("date_optional_time" ).withZone (UTC );
47
71
private static final int DEFAULT_PRECISION_FOR_CURRENT_FUNCTIONS = 3 ;
@@ -91,7 +115,17 @@ public static ZonedDateTime asDateTime(long millis, ZoneId id) {
91
115
* Parses the given string into a Date (SQL DATE type) using UTC as a default timezone.
92
116
*/
93
117
public static ZonedDateTime asDateOnly (String dateFormat ) {
94
- return LocalDate .parse (dateFormat , ISO_LOCAL_DATE ).atStartOfDay (UTC );
118
+ int separatorIdx = dateFormat .indexOf ('-' );
119
+ if (separatorIdx == 0 ) { // negative year
120
+ separatorIdx = dateFormat .indexOf ('-' , 1 );
121
+ }
122
+ separatorIdx = dateFormat .indexOf ('-' , separatorIdx + 1 ) + 3 ;
123
+ // Avoid index out of bounds - it will lead to DateTimeParseException anyways
124
+ if (separatorIdx >= dateFormat .length () || dateFormat .charAt (separatorIdx ) == 'T' ) {
125
+ return LocalDate .parse (dateFormat , ISO_LOCAL_DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL ).atStartOfDay (UTC );
126
+ } else {
127
+ return LocalDate .parse (dateFormat , ISO_LOCAL_DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE ).atStartOfDay (UTC );
128
+ }
95
129
}
96
130
97
131
public static ZonedDateTime asDateOnly (ZonedDateTime zdt ) {
@@ -109,13 +143,23 @@ public static ZonedDateTime asDateTime(String dateFormat) {
109
143
return DateFormatters .from (UTC_DATE_TIME_FORMATTER .parse (dateFormat )).withZoneSameInstant (UTC );
110
144
}
111
145
112
- public static ZonedDateTime ofEscapedLiteral (String dateFormat ) {
146
+ public static ZonedDateTime dateOfEscapedLiteral (String dateFormat ) {
147
+ int separatorIdx = dateFormat .lastIndexOf ('-' ) + 3 ;
148
+ // Avoid index out of bounds - it will lead to DateTimeParseException anyways
149
+ if (separatorIdx >= dateFormat .length () || dateFormat .charAt (separatorIdx ) == 'T' ) {
150
+ return LocalDate .parse (dateFormat , DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL ).atStartOfDay (UTC );
151
+ } else {
152
+ return LocalDate .parse (dateFormat , DATE_TIME_FORMATTER_WHITESPACE ).atStartOfDay (UTC );
153
+ }
154
+ }
155
+
156
+ public static ZonedDateTime dateTimeOfEscapedLiteral (String dateFormat ) {
113
157
int separatorIdx = dateFormat .lastIndexOf ('-' ) + 3 ;
114
158
// Avoid index out of bounds - it will lead to DateTimeParseException anyways
115
159
if (separatorIdx >= dateFormat .length () || dateFormat .charAt (separatorIdx ) == 'T' ) {
116
- return ZonedDateTime .parse (dateFormat , DATE_TIME_ESCAPED_LITERAL_FORMATTER_T_LITERAL .withZone (UTC ));
160
+ return ZonedDateTime .parse (dateFormat , DATE_TIME_FORMATTER_T_LITERAL .withZone (UTC ));
117
161
} else {
118
- return ZonedDateTime .parse (dateFormat , DATE_TIME_ESCAPED_LITERAL_FORMATTER_WHITESPACE .withZone (UTC ));
162
+ return ZonedDateTime .parse (dateFormat , DATE_TIME_FORMATTER_WHITESPACE .withZone (UTC ));
119
163
}
120
164
}
121
165
0 commit comments