fix-tzstr.pl 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #!/usr/bin/perl
  2. sub fixTzstr {
  3. # switch_time.c expects POSIX-style TZ rule, but it won't process quoted TZ
  4. # rules that look like this: <-04>4 or <-04>4<-03>
  5. # See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
  6. # Instead it defaults to UTC for these values. Here we process the quoted
  7. # values and convert them into letters. If the zone name has "GMT", we use
  8. # that as the replacement prefix, otherwise a default "STD" is used. Zones
  9. # that have a quoted suffix have their suffix replaced with "DST".
  10. my ($tzstr, $name) = @_;
  11. if ( $tzstr =~ /(<(?<std>[^>]+)>)([^<]+)(?<dst><.+>)?(?<rest>.+)?/ ) {
  12. my ($tzprefix, $tzsuffix, $tzrest, $offset, $offsetprefix) = ("") x 5;
  13. if ( defined($+{std}) ) {
  14. my $std = $+{std};
  15. if ( lc($name) =~ m/gmt/) {
  16. $tzprefix = "GMT";
  17. } else {
  18. $tzprefix = "STD";
  19. }
  20. if ( $std =~ m/\+/ ) {
  21. $offset = sprintf "%d", $std =~ s/\+//r;
  22. $offsetprefix = "-";
  23. } else {
  24. $offset = sprintf "%d", $std =~ s/\-//r;
  25. }
  26. my @chars = split(//, $offset);
  27. if ( @chars > 2 ) {
  28. my $hours = $chars[-3];
  29. if ( defined( $chars[-4] ) ) {
  30. $hours = $chars[-4].$hours;
  31. }
  32. $offset = $hours.":".$chars[-2].$chars[-1];
  33. }
  34. $offset = $offsetprefix.$offset;
  35. }
  36. if ( defined($+{dst}) ) {
  37. $tzsuffix = "DST";
  38. }
  39. if ( defined($+{rest}) ) {
  40. $tzrest = $+{rest};
  41. }
  42. return $tzprefix.$offset.$tzsuffix.$tzrest;
  43. }
  44. return $tzstr;
  45. }
  46. 1;