1

I am getting a parsing exception while I am trying the following code

    public class Timezone {

    public static void main(String[] args) {
        
        
        TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
        TimeZone tz;
        LocalDateTime now = LocalDateTime.now();
        final DateTimeFormatter ICS_DATE_FORMATTER =
                DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss");
        
        //tz = registry.getTimeZone("Asia/Calcutta");
        tz = registry.getTimeZone("Australia/Lord_Howe");
        DtStart dtstart;
        try {
        dtstart = new DtStart(now.format(ICS_DATE_FORMATTER),tz);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }    
    }
}

java.text.ParseException: Unparseable date: "20221207T170935"
    at java.base/java.text.DateFormat.parse(DateFormat.java:395)
    at net.fortuna.ical4j.model.DateTime.setTime(DateTime.java:418)
    at net.fortuna.ical4j.model.DateTime.<init>(DateTime.java:325)
    at net.fortuna.ical4j.model.property.DateProperty.setValue(DateProperty.java:137)
    at net.fortuna.ical4j.model.property.DtStart.<init>(DtStart.java:146)
    at Timezone.main(Timezone.java:33)

I have used ical4j 3.0.19 jar and their dependency jar .

Its working for all the timezone except for the timezone "Australia/Lord_Howe".

I am expecting the Dtstart value as :

DTSTART;TZID=Australia/Lord_Howe:20221207T170935

  • 2
    `DateTimeFormatter` is not being used. Your error comes from `java.text.DateFormat.parse`. Why are you mixing time APIs? – g00se Dec 07 '22 at 12:29
  • 1
    @g00se the `DateTimeFormatter` is used, but it's not the one that throws the `java.text.ParseException`, of course. – deHaar Dec 07 '22 at 12:31
  • @deHaar. I'm not quite sure what your point is. We can both see that `DateTimeFormatter` appears in the code, obviously... – g00se Dec 07 '22 at 12:33
  • I am using ical4j because i am going to use it later to write iCalendar data streams .I tried above code for timezone (ex.Asia/Calcutta).I am getting expected result without any exception. – Swati Satrusalya Dec 07 '22 at 13:01
  • @g00se Just nitpicking because the line `dtstart = new DtStart(now.format(ICS_DATE_FORMATTER),tz);` definitely (and successfully) uses the `DateTimeFormatter`. You are right, the `Exception` is not thrown by it, it's not a `DateTimeParseException`… – deHaar Dec 07 '22 at 13:08
  • 1
    OK. Actually, according to the Javadoc, it does support `java.time` so all should be well in theory. Are you using the latest version? – g00se Dec 07 '22 at 13:08
  • We should probably see the constructor of or the whole class `DtStart`. – deHaar Dec 07 '22 at 13:09
  • 1
    Try `dtstart = new DtStart(now);` – g00se Dec 07 '22 at 13:11
  • 1
    @deHaar [`DtStart` dicumentation here](https://javadoc.io/static/org.mnode.ical4j/ical4j/3.2.7/net/fortuna/ical4j/model/property/DtStart.html). – Ole V.V. Dec 07 '22 at 15:41
  • 1
    @OleV.V. looks like a case for legacy compatibility: `new DtStart(Date.from(Instant.now()), tz)` might be working. No `LocalDateTime` needed… – deHaar Dec 07 '22 at 15:49
  • And I have to correct my comment(s) (far) above: The `DateTimeFormatter` is used, but that's the problem: It's used to format the `LocalDateTime` as `String`, not for parsing it. That results in an invalid `String` representation, at least from the perspective of `DfStart`. – deHaar Dec 07 '22 at 15:51
  • 1
    There is [a version 4.0.0-beta4](https://javadoc.io/doc/org.mnode.ical4j/ical4j/latest/index.html) out where `DtStart` does support java.time. The OP would probably think twice before using it for production code immediately. @deHaar – Ole V.V. Dec 07 '22 at 15:55
  • A little debugging and experimentation revealed that the `DtStart` constructor that you are calling expects the time in UTC with a trailing `Z`, for example `20221207T060935Z` (tested with ical4j 3.2.7). – Ole V.V. Dec 07 '22 at 16:19
  • Its working for all the timezone except for the timezone "Australia/Lord_Howe". – Swati Satrusalya Dec 07 '22 at 16:22
  • Interesting! For me too it does work without `Z` with a couple time zones I tried, and with Australia/Lord_Howe only with `Z`. Can’t tell what’s special about that zone. Well, yes, indeed I can: it’s the only time zone in the world that has 30 minutes summer time transitions (standard is 1 hour). But if that would cause ical4j to behave differently??! – Ole V.V. Dec 07 '22 at 16:27
  • A further observation: passing the value `20220707T233445` does work with Australia/Lord_Howe. So maybe it only fails with summer time (DST)?? It’s beginning to look like a bug in ical4j to me. I searched a bit for a description of one, but found nothing, though. And then the value mentioned fails with time zone Antarctica/Troll (a time zone that has 2 hours summer time adjustment). :-( – Ole V.V. Dec 07 '22 at 16:54
  • 1
    yeah correct problem with summer time(DST) for Australia/Lord_howe @Ole V.V. Seems like a bug in ical4j . – Swati Satrusalya Dec 08 '22 at 09:50
  • It seems that it should be possible to [create a new issue on GitHub here](https://github.com/ical4j/ical4j/issues). – Ole V.V. Dec 10 '22 at 13:08

1 Answers1

1

No need for parsing:

package com.technojeeves.ical;

import java.util.List;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

import net.fortuna.ical4j.model.TimeZone;
import net.fortuna.ical4j.model.TimeZoneRegistry;
import net.fortuna.ical4j.model.TimeZoneRegistryFactory;
import net.fortuna.ical4j.model.property.DtStart;

import net.fortuna.ical4j.model.ParameterList;
import net.fortuna.ical4j.model.Parameter;

import net.fortuna.ical4j.model.parameter.TzId;

public class App {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        DtStart<LocalDateTime> localDtStart = new DtStart<>(now);
        System.out.println(localDtStart);
        ParameterList params = new ParameterList(List.of(new TzId("Australia/Lord_Howe")));
        DtStart<ZonedDateTime> zonedDtStart = new DtStart<>(params, ZonedDateTime.now());
        System.out.println(zonedDtStart);
    }
}

Prints

DTSTART:20221208T150844

DTSTART;TZID=Australia/Lord_Howe:20221209T020844

So far I haven't got the source of the version I'm using (4.0.0-beta4). Yes, it's a beta, but I suspect they might have supported Temporal for some time. Actually I discover that all versions 4.x support it.

My guess is that they'll fix the above ctor in time to act on ZonedDateTime as the initializing type, since, at the moment, if that's used, DtStart.toString shows no sign of the zone.

g00se
  • 3,207
  • 2
  • 5
  • 9