Skip to content

g_mime_message_set_date() and g_mime_message_get_date() and g_mime_utils_header_decode_date() fail for TAI timezoneΒ #134

Closed

Description

@riddicc

Hi!

When I use this timezone file, and when I send an email @1658946095 (date -d@1658946095 = "Wed Jul 27 18:21:45 TAI 2022"), balsa says, that the timestamp is "2022-07-27T18:22:12TAI" (format: %FT%T%Z).

balsa uses g_mime_message_set_date/g_mime_message_get_date/g_mime_utils_header_decode_date().

It seems like these functions do not behave like date(1), because: They just ignore the fractions of a minute (% 60) in tm_gmtoff.

Can you somehow fix it? I do not know why these functions do that... I just wanted to avoid those annoying leap seconds (once I thought that the crystal in my self-tinkered USB sensor phalanx is broken, when i woke up in the morning...)...

PS: Here is my bug report in the balsa issues list...

PPS: exim and s-mailx already switch to UTC and use "-0000" as timezone offset (the minus denotes a deviating time zone in accordance with RFC5322, if i understood correctly).

PPPS: fetchmail did it, too...

Thx.

Bye

Arne

Activity

  1. jstedfast commented on Nov 13, 2022

    @jstedfast
    Owner

    I would appreciate if you could test this for me. I wrote this patch from my Windows development machine which makes it non-trivial to test this.

  2. riddicc commented on Nov 13, 2022

    @riddicc
    Author

    @jstedfast thanks for that patch... i have some comments:
    line 236: "%c%05d" seems to be too long... it should be "%c%04d"... right?
    line 232: and i do not see, how day,month,year,hour,min,sec change, when u only change tz_offset... maybe "g_date_time_add_seconds" could be used to subtract (or add) the old value of tz_offset?
    tz_offset = 0; sign = '-'; } return g_strdup_printf ("%s, %02d %s %04d %02d:%02d:%02d %c%05d",

    i need to setup a build environment... is this the right way to go: git clone https://github.com/jstedfast/gmime.git ?

  3. riddicc commented on Nov 14, 2022

    @riddicc
    Author

    @jstedfast
    I found another error in ur patch (%G_TIME_SPAN_SECOND would find sub second fractions...)...
    But it still does not work... It seems like g_date_time_new_from_unix_local has a problem with my system time, too (it seems like it acts like my box does not know of leap seconds...)...

    --- ./gmime/gmime-utils.c,orig	2022-11-14 09:13:19.527160752 +0000
    +++ ./gmime/gmime-utils.c	2022-11-14 10:23:08.191705502 +0000
    @@ -217,8 +217,9 @@
     	min = g_date_time_get_minute (date);
     	sec = g_date_time_get_second (date);
     	tz = g_date_time_get_utc_offset (date);
    +printf("ARNE g_mime_utils_header_format_date: time:%jd min:%u sec:%u tz:%ld/%ld\n",time(0),min,sec,tz,G_TIME_SPAN_MINUTE);
     	
    -	if (tz % G_TIME_SPAN_SECOND == 0) {
    +	if (tz % G_TIME_SPAN_MINUTE == 0) {
     		if (tz < 0) {
     			sign = '-';
     			tz *= -1;
    @@ -229,11 +230,21 @@
     		tz_offset = 100 * (tz / G_TIME_SPAN_HOUR);
     		tz_offset += (tz % G_TIME_SPAN_HOUR) / G_TIME_SPAN_MINUTE;
     	} else {
    +		GDateTime * utcdate = g_date_time_to_utc(date);
    +		wday = g_date_time_get_day_of_week (utcdate);
    +		year = g_date_time_get_year (utcdate);
    +		month = g_date_time_get_month (utcdate);
    +		day = g_date_time_get_day_of_month (utcdate);
    +		hour = g_date_time_get_hour (utcdate);
    +		min = g_date_time_get_minute (utcdate);
    +		sec = g_date_time_get_second (utcdate);
    +		g_date_time_unref(utcdate);
    +printf("ARNE g_mime_utils_header_format_date: fracMIN min:%u sec:%u\n",min,sec);
     		tz_offset = 0;
     		sign = '-';
     	}
     	
    -	return g_strdup_printf ("%s, %02d %s %04d %02d:%02d:%02d %c%05d",
    +	return g_strdup_printf ("%s, %02d %s %04d %02d:%02d:%02d %c%04d",
     				tm_days[wday % 7], day, tm_months[month - 1],
     				year, hour, min, sec, sign, tz_offset);
     }
    

    this is the output of my test:

    > balsa
    ARNE g_mime_utils_header_format_date: time:1668421497 min:25 sec:34 tz:37000000/60000000
    ARNE g_mime_utils_header_format_date: fracMIN min:24 sec:57
    >  date -d@1668421497
    Mon Nov 14 10:25:07 TAI 2022
    >  TZ=UTC date -d@1668421497
    Mon Nov 14 10:24:30 UTC 2022
    
  4. jstedfast commented on Nov 14, 2022

    @jstedfast
    Owner

    Thanks, I've made the corrections and folded them into my original patch (with a force push)..

  5. jstedfast commented on Nov 14, 2022

    @jstedfast
    Owner

    Interesting... C#/.NET does not allow timezones with non-0 seconds:

    var date = new DateTimeOffset (2022, 11, 14, 10, 25, 07, new TimeSpan (0, 0, 37));
    var timestamp = DateUtils.FormatDate (date);
    
    Assert.AreEqual ("Mon, 14 Nov 2022 10:24:30 -0000", timestamp);

    Result:

    Message: 
    System.ArgumentException : Offset must be specified in whole minutes. (Parameter 'offset')
    
      Stack Trace: 
    DateTimeOffset.ValidateOffset(TimeSpan offset)
    DateTimeOffset.ctor(Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, TimeSpan offset)
    DateParserTests.TestFormatDateWithNonStandardTimezone() line 164
    
  6. riddicc commented on Nov 14, 2022

    @riddicc
    Author

    @jstedfast how do g_date_time_get_second and g_date_time_new_from_unix_local work? I mean: Do they use the system routines? or do they try to circumvent the zoneinfo files?

  7. jstedfast commented on Nov 14, 2022

    @jstedfast
    Owner

    You'd have to ask the GLib developers. I'm not sure how the internals of those functions work.

  8. riddicc commented on Nov 16, 2022

    @riddicc
    Author

    @jstedfast Uhm... Glib intentionally circumvents the system time routines and ignores POSIX...

    can gmime take care of this, since it is talking to POSIX compliant systems?

    I would recommend to use gmtime(3) and localtime(3)...

  9. jstedfast commented on Nov 16, 2022

    @jstedfast
    Owner

    Are things still not working? I don't understand why I need to bypass Glib's time routines now.

  10. riddicc commented on Nov 16, 2022

    @riddicc
    Author

    @jstedfast it seems like GLib still uses the original meaning of "seconds since 1970"... GLib acts like there are no leap seconds...

    So gmime would have to use functions like strptime(3) and strftime(3) to be POSIX and RFC5322 compliant, i guess...

    But maybe GLib changes its mind... i cant say that... I am ok with my balsa patch...

    I just thought, that gmime or GLib might want to be leap seconds aware... 🫣

  11. riddicc commented on Nov 30, 2022

    @riddicc
    Author

    it seems like GLib wants to circumvent the system routines with their own custom routines... i wonder if javascript also uses GLib, because: It has at least a similar problem... πŸ˜€

    what about a RFC5322-compliance check, when gmime tries to make a human-readable timestamp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions