sabre-io / vobject

:date: The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects
http://sabre.io/vobject/
BSD 3-Clause "New" or "Revised" License
570 stars 125 forks source link

FreeBusy Period serialization to JSON removes UTC indicator (Z) #411

Open renaudboyer opened 6 years ago

renaudboyer commented 6 years ago

When serializing FreeBusy Period objects to JSON, UTC Z is stripped from date. Json dates are in local time instead of UTC (if I've got the Iso8601 correctly)

Shouldn't Json dates have the Z like iCal ?

I have a PR ready here to update this here

Here's the iCal (headers have been removed)

BEGIN:VCALENDAR
BEGIN:VFREEBUSY
DTSTART:20180302T000000Z
DTEND:20180307T000000Z
DTSTAMP:20180418T074609Z
FREEBUSY:20180302T100000Z/20180302T110000Z
END:VFREEBUSY
END:VCALENDAR

is serialized to

[
  "vcalendar",
  [
    [
      "vfreebusy",
      [
        [
          "dtstart", {},
          "date-time", "2018-03-02T00:00:00Z"
        ],
        [
          "dtend", {},
          "date-time", "2018-03-07T00:00:00Z"
        ],
        [
          "dtstamp", {},
          "date-time", "2018-04-18T07:57:26Z"
        ],
        [
          "freebusy", {},
          "period",
          [
            "2018-03-02T10:00:00",
            "2018-03-02T11:00:00"
          ]
        ]
      ],
      []
    ]
  ]
]
DominikTo commented 6 years ago

Is this the same object? In your iCalendar document DTSTAMP is 20180418T074609Z. In the JSON document it's 2018-04-18T07:57:26Z.

I only had a very quick look. If I understand L290 here correctly, we are adding the Z in L296 if all of the following are true:

But on first glance I am also confused, why the Free-Busy Info has no TZ info. Maybe @evert has an idea?

evert commented 6 years ago

I'm not sure why it's happening, but I can reproduce it

renaudboyer commented 6 years ago

PERIOD deal with dates by itself when serializing to jCal ( here ). There are no TZ in PERIOD, they are handled by parent component like this: RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H.

PERIOD's dates are parsed to Php with with UTC TZ in any cases ( here ). Then formatted without the Z ( here ).

I think adding Z, if date in VALUE has Z (using something similar to isUtc) should work. UTC Date will have the Z indicator and floating dates or dates with TZ in parent component won't change.