2020
2121import java .text .ParseException ;
2222import java .text .SimpleDateFormat ;
23- import java .time .ZonedDateTime ;
23+ import java .time .*;
24+ import java .time .format .DateTimeFormatter ;
25+ import java .time .format .DateTimeFormatterBuilder ;
26+ import java .time .format .DateTimeParseException ;
27+ import java .time .temporal .ChronoField ;
28+ import java .time .temporal .TemporalAccessor ;
2429import java .util .ArrayList ;
2530import java .util .Calendar ;
2631import java .util .Date ;
@@ -39,25 +44,29 @@ public class DateUtils {
3944 // Per IBM LEEF guide at https://www.ibm.com/support/knowledgecenter/SS42VS_DSM/c_LEEF_Format_Guide_intro.html
4045 public static List <SimpleDateFormat > DATE_FORMATS_LEEF = new ArrayList <SimpleDateFormat >() {
4146 {
42- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss.SSS zzz" ));
43- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss.SSS" ));
44- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss" ));
47+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS Z" ));
48+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS z" ));
49+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS" ));
50+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss" ));
4551 }
4652 };
4753
4854 public static List <SimpleDateFormat > DATE_FORMATS_CEF = new ArrayList <SimpleDateFormat >() {
4955 {
5056 // as per CEF Spec
51- add (new SimpleDateFormat ("MMM dd HH:mm:ss.SSS zzz" ));
52- add (new SimpleDateFormat ("MMM dd HH:mm:ss.SSS" ));
53- add (new SimpleDateFormat ("MMM dd HH:mm:ss zzz" ));
54- add (new SimpleDateFormat ("MMM dd HH:mm:ss" ));
55- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss.SSS zzz" ));
56- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss.SSS" ));
57- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss zzz" ));
58- add (new SimpleDateFormat ("MMM dd yyyy HH:mm:ss" ));
57+ add (new SimpleDateFormat ("MMM d HH:mm:ss.SSS Z" ));
58+ add (new SimpleDateFormat ("MMM d HH:mm:ss.SSS z" ));
59+ add (new SimpleDateFormat ("MMM d HH:mm:ss.SSS" ));
60+ add (new SimpleDateFormat ("MMM d HH:mm:ss zzz" ));
61+ add (new SimpleDateFormat ("MMM d HH:mm:ss" ));
62+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS Z" ));
63+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS z" ));
64+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss.SSS" ));
65+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss Z" ));
66+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss z" ));
67+ add (new SimpleDateFormat ("MMM d yyyy HH:mm:ss" ));
5968 // found in the wild
60- add (new SimpleDateFormat ("dd MMMM yyyy HH:mm:ss" ));
69+ add (new SimpleDateFormat ("d MMMM yyyy HH:mm:ss" ));
6170 }
6271 };
6372
@@ -103,22 +112,33 @@ public static long parseMultiformat(String candidate, List<SimpleDateFormat> val
103112 } else {
104113 for (SimpleDateFormat pattern : validPatterns ) {
105114 try {
106- Calendar cal = Calendar . getInstance ();
107- cal . setTime (pattern .parse ( candidate ));
108- Calendar current = Calendar . getInstance ();
109- if ( cal . get ( Calendar . YEAR ) == 1970 ) {
110- cal . set ( Calendar .YEAR , current . get ( Calendar . YEAR ));
115+ DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder ()
116+ . appendPattern (pattern .toPattern ( ));
117+ if (! pattern . toPattern (). contains ( "y" )) {
118+ formatterBuilder
119+ . parseDefaulting ( ChronoField .YEAR , LocalDate . now (). getYear ( ));
111120 }
112- current .add (Calendar .DAY_OF_MONTH , 4 );
113- if (cal .after (current )) {
114- cal .add (Calendar .YEAR , -1 );
121+ DateTimeFormatter formatter = formatterBuilder .toFormatter ();
122+ ZonedDateTime parsedValue = parseDateTimeWithDefaultTimezone (candidate , formatter );
123+ ZonedDateTime current = ZonedDateTime .now (parsedValue .getZone ());
124+
125+ current = current .plusDays (4 );
126+ if (parsedValue .isAfter (current )) {
127+ parsedValue = parsedValue .minusYears (1 );
115128 }
116- return cal . getTimeInMillis ();
117- } catch (ParseException e ) {
129+ return parsedValue . toInstant (). toEpochMilli ();
130+ } catch (DateTimeParseException e ) {
118131 continue ;
119132 }
120133 }
121134 throw new ParseException ("Failed to parse any of the given date formats" , 0 );
122135 }
123136 }
137+
138+ private static ZonedDateTime parseDateTimeWithDefaultTimezone (String candidate , DateTimeFormatter formatter ) {
139+ TemporalAccessor temporalAccessor = formatter .parseBest (candidate , ZonedDateTime ::from , LocalDateTime ::from );
140+ return temporalAccessor instanceof ZonedDateTime
141+ ? ((ZonedDateTime ) temporalAccessor )
142+ : ((LocalDateTime ) temporalAccessor ).atZone (ZoneId .systemDefault ());
143+ }
124144}
0 commit comments