HiraokaHyperTools / msgreader

35 stars 9 forks source link

clipStart & clipEnd to get start & end date of recurring appointment #32

Closed PixelsByLucas closed 1 year ago

PixelsByLucas commented 1 year ago

I'm trying to use clipStart & clipEnd to get the date of the first instance & last instance in a recurring appointment series. It seems these properties contain a GMT date with the time of midnight.

The issue I'm having is that this date seems to be relative to the time zone where the appointment was created (I think). For example, if an appointment was created in the UK it will produce a clipStart of Wed, 30 Nov 2022 00:00:00 GMT. This same appointment created in Eastern Standard Time seems to produce a clipStart of Tue Nov 29 2022 19:00:00 GMT. (GMT-0500).

This only seems to be the case for recurring appointments where the time defaults to midnight. apptEndWhole, apptStartWhole & messageDeliveryTime all seem to produce GMT dates that have an offset to account for the recipient's local time zone.

Is this expected behavior? If so how can I obtain series dates that accurately reflect the recipient's local time zone?

kenjiuno commented 1 year ago

For now msgreader doesn't process anything about timezone.

msg file's datetime representation is Win32's FILETIME. This doesn't contain about timezone, because it assumes UTC based...

I have searched about timezone properties. There are some results hit.

And also

Some of them may be usable my msgreader. I'll check more about this.

kenjiuno commented 1 year ago

The issue I'm having is that this date seems to be relative to the time zone where the appointment was created (I think).

This seems to be right.

I have created sample appointment msg file, and parsed json:

https://github.com/HiraokaHyperTools/msgreader/blob/master/test/7%20days%20%20everyday.msg https://github.com/HiraokaHyperTools/msgreader/blob/master/test/7%20days%20%20everyday.json

JST (Japan Standard Time) is GMT+0900

"clipStart": "Wed, 30 Nov 2022 15:00:00 GMT", "clipEnd": "Tue, 06 Dec 2022 15:00:00 GMT"

This will point a period among 12/1 ~ 12/7 in Japan.

Is this expected behavior? If so how can I obtain series dates that accurately reflect the recipient's local time zone?

Probably yes.

To help out time zone problem, I have added some parsed properties.

 "timeZoneDesc": "(UTC+09:00) 大阪、札幌、東京",
 "timeZoneStruct": {
  "bias": -540,
  "standardBias": 0,
  "daylightBias": -60,
  "standardYear": 0,
  "standardDate": null,
  "daylightYear": 0,
  "daylightDate": null
 },
 "apptTZDefRecur": {
  "rules": [
   {
    "flags": 2,
    "start": "Mon, 01 Jan 1601 00:00:00 GMT",
    "bias": -540,
    "standardBias": 0,
    "daylightBias": -60,
    "standardDate": null,
    "daylightDate": null
   }
  ],
  "keyName": "Tokyo Standard Time"
 },

Currently no further decoding is provided yet. I don't verify appointment msg files so much now.

The sample JSON have these properties too https://github.com/HiraokaHyperTools/msgreader/blob/master/test/7%20days%20%20everyday.json

The doc is updated too https://hiraokahypertools.github.io/msgreader/typedoc/interfaces/MsgReader.FieldsData.html

Try @kenjiuno/msgreader@1.17.0-alpha.3

PixelsByLucas commented 1 year ago

Thank you so much for this. Apologies but I've got some questions.

I see your bias from Tokyo Standard Time as -540. Shouldn't this be 540 as it's GMT+9? Likewise the bias I'm seeing for Eastern Standard Time is 300. But I would expect -300 as it's GMT-5.

The main difference between apptTZDefRecur & timeZoneStruct is that apptTZDefRecur provides future, past, present time zone rules, whereas timeZoneStruct only provides present rules?

I'm also confused about TzDefinitionRule. To find the correct rule to apply to clipStart/clipEnd I should check the start property of each rule? I thought perhaps I could use the "flags": 2 property to determine which is the "effective rule". But that's relative to the current time, not relative to clipStart/clipEnd. Is that right?

Once I've found the correct rule, I can use the standardDate & daylightDate properties to determine whether to apply standardBias or daylightBias to the rule's bias. Is that correct?

Below is what I'm receiving for Eastern Standard Time. The standardDate & daylightDate look incorrect to me. They have a year of 0000, and I would expect daylight saving time to begin March 13 and end Nov 6 for rules[1].

apptTZDefRecur: {
    "keyName":  "Eastern Standard Time",
    "rules": [
        {
            "flags": 0,
            "start": "Sun, 01 Jan 2006 00:00:00 GMT",
            "bias": 300,
            "standardBias": 0,
            "daylightBias": -60,
            "standardDate": "Thu, 05 Oct 0000 02:00:00 GMT",
            "daylightDate": "Sat, 01 Apr 0000 02:00:00 GMT"
        },
        {
            "flags": 2,
            "start": "Mon, 01 Jan 2007 00:00:00 GMT",
            "bias": 300,
            "standardBias": 0,
            "daylightBias": -60,
            "standardDate": "Wed, 01 Nov 0000 02:00:00 GMT",
            "daylightDate": "Thu, 02 Mar 0000 02:00:00 GMT"
        }
    ],
    "keyName": "Eastern Standard Time"
}
kenjiuno commented 1 year ago

Outlook is a pure Windows Desktop app, so the rules of time zone & daylight saving time may be subjected by Windows's processing way. I missed about this.

TIME_ZONE_INFORMATION documentation will help out to understand bias, standardBias, daylightBias, standardDate and daylightDate.

TIME_ZONE_INFORMATION (timezoneapi.h) - Win32 apps | Microsoft Learn

About flags, "flags": 2 will be good mark to decide.

TZRULE_FLAG_EFFECTIVE_TZREG (2) — Identifies the rule as the one that should be used currently. Only one rule can be marked as the effective rule. All other rules are for comparison purposes only.

TzDefinitionRule | @kenjiuno/msgreader - v1.17.0-alpha.3

kenjiuno commented 1 year ago

I need to fix processing way of SYSTEMTIME of standardDate and daylightDate, before you can access wDayOfWeek and so on correctly. SYSTEMTIME is once converted into JavaScript Date, and some of SYSTEMTIME members are lost and incorrect.

kenjiuno commented 1 year ago

@kenjiuno/msgreader@1.17.0-alpha.4 has been published.

I added EST appointment sample https://github.com/HiraokaHyperTools/msgreader/blob/master/test/Appointment%20sample%20EST.json

In this sample timeZoneDesc is JST. timeZoneDesc will be currently selected time zone at Windows settings.

 "timeZoneDesc": "(UTC+09:00) 大阪、札幌、東京",

apptTZDefStartDisplay and apptTZDefEndDisplay are EST that I have selected from appointment's time zone.

 "apptTZDefStartDisplay": {
  "rules": [
   {
    "flags": 2,
    "start": "Mon, 01 Jan 2007 00:00:00 GMT",
    "bias": 300,
    "standardBias": 0,
    "daylightBias": -60,
    "standardDate": {
     "year": 0,
     "month": 11,
     "dayOfWeek": 0,
     "day": 1,
     "hour": 2,
     "minute": 0
    },
    "daylightDate": {
     "year": 0,
     "month": 3,
     "dayOfWeek": 0,
     "day": 2,
     "hour": 2,
     "minute": 0
    }
   }
  ],
  "keyName": "Eastern Standard Time"
 },
 "apptTZDefEndDisplay": {
  "rules": [
   {
    "flags": 0,
    "start": "Sun, 01 Jan 2006 00:00:00 GMT",
    "bias": 300,
    "standardBias": 0,
    "daylightBias": -60,
    "standardDate": {
     "year": 0,
     "month": 10,
     "dayOfWeek": 0,
     "day": 5,
     "hour": 2,
     "minute": 0
    },
    "daylightDate": {
     "year": 0,
     "month": 4,
     "dayOfWeek": 0,
     "day": 1,
     "hour": 2,
     "minute": 0
    }
   },
   {
    "flags": 2,
    "start": "Mon, 01 Jan 2007 00:00:00 GMT",
    "bias": 300,
    "standardBias": 0,
    "daylightBias": -60,
    "standardDate": {
     "year": 0,
     "month": 11,
     "dayOfWeek": 0,
     "day": 1,
     "hour": 2,
     "minute": 0
    },
    "daylightDate": {
     "year": 0,
     "month": 3,
     "dayOfWeek": 0,
     "day": 2,
     "hour": 2,
     "minute": 0
    }
   }
  ],
  "keyName": "Eastern Standard Time"
 },

apptTZDefRecur is missing.

apptTZDefRecur will be available when Recurrence is turned on.

2022-12-03_15h36_08

2022-12-03_15h37_53

PixelsByLucas commented 1 year ago

Okay thank you. I understand now. I played around with this a bit and it looks like it should work. So this can probably be closed now.

It's a bit low level though.
Do you expect to keep the new alpha tz properties in major versions going forward? I guess it's not possible for you to expose series start/end date that doesn't try to set time to 00:00? I guess the reason time is set to 00:00 is because individual instances in a series could have different times.

kenjiuno commented 1 year ago

Hi

Do you expect to keep the new alpha tz properties in major versions going forward?

Yes these changes will be kept, and it will be available since next minor 1.17.0.

I guess it's not possible for you to expose series start/end date that doesn't try to set time to 00:00? I guess the reason time is set to 00:00 is because individual instances in a series could have different times.

I remembered that your question is about first instance & last instance in a recurring appointment series.

The property about recurring itself is not extracted/decoded by the library yet.

This property will be required to satisfy what you want to do.

I'll check about this.

kenjiuno commented 1 year ago

@kenjiuno/msgreader@1.17.0-alpha.5 will parse apptRecur

sample:

https://github.com/HiraokaHyperTools/msgreader/blob/1b00c6fbc6f0c01492d17f757b67fac03eaaa3dd/test/Lanch%20time%20%20every%20friday%20%20in%202023%20chgs2.json#L231-L271

doc: FieldsData | @kenjiuno/msgreader - v1.17.0-alpha.5

Make sure that recurring can hold "individually cancelled schedules" and "individually rescheduled schedules", as ExceptionInfo.

PixelsByLucas commented 1 year ago

This is great. apptRecur looks really useful.

Not sure if it's useful without the msg file but: image

kenjiuno commented 1 year ago

Hi.

AppointmentRecur is conditional data format, and msgreader might fail on a certain condition due to bugs.

Is it possible to share .msg file you have tried?

PixelsByLucas commented 1 year ago

Sorry, I was afk for a little while. No, unfortunately I cannot share this .msg file.

kenjiuno commented 1 year ago

@kenjiuno/msgreader@1.17.0-alpha.8 may help fix bug of parser.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 1 year ago

This issue was closed because it has been inactive for 14 days since being marked as stale.