-5

I will be having a String in ISO-8601 format with - and : i.e., 20170609T184237Z

Whats the best way to

  1. Validate input string
  2. Convert it into milliseconds string

The only way I could think of is create a DateTime object and then from there convert it into milliseconds and then String. Is there a better way?

Em Ae
  • 8,167
  • 27
  • 95
  • 162
  • you can try parsing and then catching the exception, if there is no exception, then you will get an object of the LocalDateTime from which you can get all the info you need – ΦXocę 웃 Пepeúpa ツ Jun 12 '17 at 15:21
  • 4
    where is the **-** and **:** in this: **0170609T184237Z** ???? – ΦXocę 웃 Пepeúpa ツ Jun 12 '17 at 15:23
  • 1
    "I will be having string in ISO-8601 format with - and : i.e., 20170609T184237Z" - This example doesn't match your description. – Tom Jun 12 '17 at 15:23
  • @ΦXocę웃Пepeúpaツ `20170609T184237Z` = `2017-06-09T184:23:7Z` – Krupip Jun 12 '17 at 15:25
  • 4
    @snb 184 o'clock is pretty late ... – Tom Jun 12 '17 at 15:27
  • One way is to convert it into a date with SimpleDateFormat and then parse it. If you get an exception then it is not valid, handle the exception and all is good. I would create a boolean method to parse the date which returns false if an exception was thrown or true otherwise. Not to have the exception being thrown in your main method. – Louis Papaloizou Jun 12 '17 at 15:44
  • What have you tried? What did your search engine tell you? – Ole V.V. Jun 12 '17 at 19:01
  • 1
    @LouisPapaloizou, don’t use `SimpleDateFormat`. And especially don’t teach the young ones to use it. It’s so old-school now. And poorly designed. Use `java.time` or the backport to Java 6 and 7. For Android, use [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP). – Ole V.V. Jun 12 '17 at 19:32
  • FYI, the format of your input string complies with the “basic” version of the standard [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, where 'basic' means minimizing the use of separators. The expanded format is `2017-06-09T18:42:37Z` which can be parsed directly by the `java.time.Instant` class. – Basil Bourque Jun 13 '17 at 07:32
  • 2
    Dear Down-Voters: Please leave a criticism along with your vote. You may be thinking this is an obvious duplicate - so did I. I checked, and this is *not* a duplicate… While there are similar Questions, all the ones I found lacked the `Z` and lacked any offset or time zone. So this does seem to be a legitimate Question to me. – Basil Bourque Jun 13 '17 at 07:34
  • I didn’t downvote (also @BasilBourque). One may only speculate that downvotes are because of lack of effort on the asker’s part. Close reasons voted for so far include “Too broad” and “Unclear what you are asking” (I also didn’t vote to close). – Ole V.V. Jun 13 '17 at 07:58
  • I certainly agree that one should leave an explanation when downvoting. – Ole V.V. Jun 13 '17 at 08:00

1 Answers1

2

I am assuming you meant without - and :. No, your way of parsing into some appropriate date-time object and converting to milliseconds is good and standard, there isn’t really anything better.

Did you intend to use Joda-Time? You may want to think again. The Joda-Time homepage says

Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).

JSR-310 is also backported to Java 6 and 7, so I would suggest using that backport in preferrence to Joda-Time.

The following is probably more than you asked for. I suggest a method like:

/**
 * 
 * @param dateTimeString String in 20170609T184237Z format
 * @return milliseconds since the epoch as String
 * @throws IllegalArgumentException if the String is not in the correct format
 */
private static String isoToEpochMillis(String dateTimeString) {
    try {
        OffsetDateTime dateTime = OffsetDateTime.parse(dateTimeString,
                DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmssX"));
        if (! dateTime.getOffset().equals(ZoneOffset.UTC)) {
            throw new IllegalArgumentException("Offset is not Z");
        }
        return String.valueOf(dateTime.toInstant().toEpochMilli());
    } catch (DateTimeException dte) {
        throw new IllegalArgumentException("String is not in format uuuuMMddTHHmmssZ",
                                           dte);
    }
}

Let’s call it like this:

    String milliseconds = isoToEpochMillis("20170609T184237Z");
    System.out.println(milliseconds);

This prints

1497033757000

I don’t know how strict of a validation you want. Your example string has Z time zone; As you can see, I am requiring UTC time zone, but will also accept for example 20170609T184237+00. If that must be Z, I think you need to use dateTimeString.endsWith("Z").

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • thanks, what if i don't want to care about timezone? – Em Ae Jun 12 '17 at 20:11
  • 2
    First, you *do* want to care about time zone in the sense that the correct number of milliseconds depends on the time zone. Second, you will need to decide which time zone formats you will accept since there is a wealth of them (America/Los_Angeles; Z; -08:30; Pacific Standard Time; PST; GMT+8; US/Eastern; -083015; -08:30:15). – Ole V.V. Jun 12 '17 at 20:15
  • 2
    The `X` in my format pattern string accepts an offset, not a time zone (`Z` counts as the zero offset). The easy answer to your question is you delete the if statement checking that the offset is UTC (AKA Z). If you want to accept a real time zone too (like America/Los_Angeles), we should probably be a bit more creative. I’m prepared to take a look at your requirements if you can tell me just approximately what they are. – Ole V.V. Jun 12 '17 at 20:19