2

In my csv file I have column contains date like this :

my_col,...
2016-06-28 21:05:56 ADT
2016-06-28 22:05:56 ADT
2016-06-28 23:05:56 ADT

I have to map this CSV file to a Java object.

I tried multiple solution like :

final String str = "2016-06-28 14:18:28 ADT";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss");
LocalDateTime ld2 = LocalDateTime.parse( str , f ) ;

But I have error :

java.time.format.DateTimeParseException: Text '2016-06-28 14:18:28 ADT' could not be parsed, unparsed text found at index 19

How can I convert this kind of date (2016-06-28 14:18:28 ADT) to my Java field?

And which API shows me how to map a CSV file to a list of Java objects?

Miki
  • 40,887
  • 13
  • 123
  • 202
adaso
  • 61
  • 5
  • Your data needs to match your pattern, and you've got an "ADT" in there you're not accounting for. – azurefrog Oct 11 '19 at 21:15
  • i dont know what is the ADT in my dates. i have to read the csv file as it is an theses dates must be stored in my java object, i dont know realy how to do after several tests, – adaso Oct 11 '19 at 21:17
  • 1
    It's the [timezone](https://www.timeanddate.com/time/zones/adt) – Curiosa Globunznik Oct 11 '19 at 21:17
  • Change your format to `yyyy-MM-dd HH:mm:ss zzz`, from the [JavaDocs](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html), *"z | time-zone name | zone-name | Pacific Standard Time; PST"* – MadProgrammer Oct 11 '19 at 21:21
  • please can you give me a peace of code that permit me when i read my column = "2016-06-28 21:05:56 ADT" as it is, to store it in a java field ? – adaso Oct 11 '19 at 21:21
  • the peace of code is difficult to obtain... – Curiosa Globunznik Oct 11 '19 at 21:22
  • i tried this : final String dateTime1 = "2016-06-29 00:38:03 ADT"; DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT; final ZonedDateTime parsed = ZonedDateTime.parse(dateTime1, formatter.withZone(ZoneId.of("Canada/Atlantic")));--final String str = "2016-06-29 00:38:03 ADT"; DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss"); LocalDate ld = LocalDate.parse( str , DateTimeFormatter.ISO_LOCAL_DATE ) ; LocalDate ld = LocalDate.parse( str , f ) ; no one work – adaso Oct 11 '19 at 21:27
  • 1
    I suggest you educate the publisher of your CSV data about the practice of communicating moments by using [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) (an offset of zero) and [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). In Java, see the [`Instant`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Instant.html) class. – Basil Bourque Oct 12 '19 at 04:09

1 Answers1

1

For reading csv in java you could use libraries like e.g. this one.

As for the question in which attribute/object the parsed date should end up

"so my java object field must be of type : ZonedDateTime ?" No, you could use a string, split it in several Integers, use DateTime plus a String for the time zone ... as you like it.

As for your pattern, check out the oracle documentation on datetimeformatter patterns, you can use this:

DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss z");
System.out.println(ZonedDateTime.parse("2016-06-28 14:18:28 ADT", f));
    says "2016-06-28T14:18:28-03:00[SystemV/AST4ADT]"

where "SystemV/AST4ADT" on one side shows up in respectable lists but on the other side seems to be an outdated convention (from SystemV).

Now in comments it has been noted that the same input string on other systems yields

2016-06-28T14:18:28-03:00[America/Halifax]

and I think, that can be traced back to the setup of your local system, more precisely, the jvm time zone settings and the local time zone of your machine (see below).

Considering the additional info from the comments it becomes clear, that you can't realiably recover "ADT" (literally) from your input string, taking the route over ZonedDateTime. If you want to retain it, something like "2016-06-28 14:18:28 ADT".substring(21) might be the most economical version, ugly as it is. I'd take it.

There are alternatives, though. Chances are, all your date values stem from the same time zone anyway and you don't need it in the first place. If you do, you could create a mapping between all possible time zones, 425 at the moment, to their abbreviations (zonedDateTime.getZone()->String).

Now it's getting really esoteric, there appears to be a mysterious time zone updater tool by Oracle, which is supposed to keep JVM's time zones up to date and which takes it's values from a time zone database, the currently maintained version is IANA's Time Zone Database, when downloaded it contains an theory.html with a section "Time zone abbreviations" which says: "When this package is installed, it generates time zone abbreviations like 'EST' to be compatible with human tradition and POSIX". Then I discovered to my delight that on linux there's the zdump command which responds to zdump Canada/Atlantic UTC with

Canada/Atlantic Sat Oct 12 03:39:19 2019 ADT

You can extract the whole list, I put the command and the output in a github gist. What you don't get is a decoding for e.g "SystemV/AST4ADT". The whole SystemV nomenclature seems to be deprecated, so I wonder, how this pops up in ZonedDateTime. Where I eventually found it was the "systemv" file in ican's database, you can find the relevant content below.

There's also a web service provider out there where you can find a hopefully complete list of time zones plus abbreviations and you could probably use the service, if you're into this kind of thing. Doesn't account for stuff like "SystemV/AST4ADT", though.

Content of "systemv" file, you'd have to map to the Time Zone Database abbreviations using the GMT-offsets (like -4:00)

tzdb data for System V rules (this file is obsolete)
Zone    NAME        STDOFF  RULES/SAVE  FORMAT  [UNTIL]
Zone    SystemV/AST4ADT -4:00   SystemV     A%sT
Zone    SystemV/EST5EDT -5:00   SystemV     E%sT
Zone    SystemV/CST6CDT -6:00   SystemV     C%sT
Zone    SystemV/MST7MDT -7:00   SystemV     M%sT
Zone    SystemV/PST8PDT -8:00   SystemV     P%sT
Zone    SystemV/YST9YDT -9:00   SystemV     Y%sT
Zone    SystemV/AST4    -4:00   -       AST
Zone    SystemV/EST5    -5:00   -       EST
Zone    SystemV/CST6    -6:00   -       CST
Zone    SystemV/MST7    -7:00   -       MST
Zone    SystemV/PST8    -8:00   -       PST
Zone    SystemV/YST9    -9:00   -       YST
Zone    SystemV/HST10   -10:00  -       HST
Curiosa Globunznik
  • 3,129
  • 1
  • 16
  • 24
  • thank you, i tried this : final String str = "2016-06-29 00:38:03 ADT"; DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss"); LocalDate ld = LocalDate.parse( str , DateTimeFormatter.ISO_LOCAL_DATE ) ; LocalDate ld = LocalDate.parse( str , f ) ; i obtainer : 2016-06-28T14:18:28 but if i want re writ since my java field to csv file how can i obtain again the : "2016-06-28 14:18:28 ADT" ? – adaso Oct 11 '19 at 21:31
  • why don't you go with the pattern above? It's tested for your case. Note the "z" at the end. "yyyy-MM-dd HH:mm:ss **z**" If you're asking, how to preserve the "ADT" with LocalDate, you can't. From the [oracle documentation](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html): "A date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03. " – Curiosa Globunznik Oct 11 '19 at 21:32
  • yes I tried this code : `final String str = "2016-06-28 14:18:28 ADT"; DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss z"); LocalDateTime ld2 = LocalDateTime.parse( str , f ) ; System.out.println(ld2);` i obtained this : 2016-06-28T14:18:28. but i should re write from the java filed to csv file so from : "2016-06-28T14:18:28" i should obtain again "2016-06-28 14:18:28 ADT" to re write it as it is in my csv file how can i do that please? – adaso Oct 11 '19 at 21:43
  • thank you, i tried this : final String str = "2016-06-29 00:38:03 ADT"; DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss"); LocalDate ld = LocalDate.parse( str , DateTimeFormatter.ISO_LOCAL_DATE ) ; LocalDate ld = LocalDate.parse( str , f ) ; i obtainer : 2016-06-28T14:18:28 but if i want re writ since my java field to csv file how can i obtain again the : "2016-06-28 14:18:28 ADT" ? – adaso Oct 11 '19 at 21:47
  • As said, DateTime won't serve for this purpose. But after it parsed successfully, you know that the last 3 letters in the original string will be a time zone. So you could fiddle with substring and string concatenation to get your result. Or use [ZonedDateTime](https://howtodoinjava.com/java/date-time/convert-date-between-timezones/), I have no experience with that, though. – Curiosa Globunznik Oct 11 '19 at 21:48
  • 1
    there is no maner to done it for exemple by `ZoneId zone = ZoneId.of("Canada/Atlantic");` instead of concat manualy "ADT" ? – adaso Oct 11 '19 at 21:51
  • I just took the pattern from above for `ZonedDateTime.parse("2016-06-28 14:18:28 ADT", f)` gives you "2016-06-28T14:18:28-03:00[SystemV/AST4ADT]", where "SystemV/AST4ADT" seems to be the [official name for ADT](https://www.ibm.com/support/knowledgecenter/SS97LW_2.2.4/doc/psapsys_restapi/time_zone_list.html) – Curiosa Globunznik Oct 11 '19 at 21:55
  • I didn't mean to concat "ADT" manuall, I meant to concat `"2016-06-28 14:18:28 ADT".substring(21)` – Curiosa Globunznik Oct 11 '19 at 22:00
  • so my java object field must be of type : ZonedDateTime ? – adaso Oct 11 '19 at 22:17
  • @adaso Read the Question: [*What's the difference between Instant and LocalDateTime?*](https://stackoverflow.com/q/32437550/642706) to learn about the data types in *java.time*. Use Instant for UTC, OffsetDateTime for offsets, and ZonedDateTime for named time zones. – Basil Bourque Oct 12 '19 at 04:15
  • ADT (like so many time zone abbreviations) is ambiguous. If Arabia Daylight Time was intended, there isn’t one official ID. You may try Asia/Amman, for example, depending on country, If it’s for Atalantic Daylight TIme, I believe America/Halifax is the official ID. All official time zone IDs have the *region/city* format. – Ole V.V. Oct 12 '19 at 04:43
  • I do get `2016-06-28T14:18:28-03:00[America/Halifax]` when pasting your code into `jshell` (REPL). – Ole V.V. Oct 12 '19 at 04:51
  • on linux `zdump Canada/Atlantic UTC` will yield `Canada/Atlantic Sat Oct 12 03:39:19 2019 ADT` – Curiosa Globunznik Oct 12 '19 at 06:40