~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/tztime.cc

  • Committer: Brian Aker
  • Date: 2008-07-31 19:57:34 UTC
  • mfrom: (236.1.27 codestyle)
  • Revision ID: brian@tangent.org-20080731195734-c7cu4gx70xgjr68o
Merge from Monty.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <libdrizzle/my_time.h>
22
22
 
23
23
#include "tzfile.h"
24
 
#include <m_string.h>
25
24
 
26
25
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
27
26
typedef struct ttinfo
44
43
 
45
44
/*
46
45
  Structure with information describing ranges of my_time_t shifted to local
47
 
  time (my_time_t + offset). Used for local MYSQL_TIME -> my_time_t conversion.
 
46
  time (my_time_t + offset). Used for local DRIZZLE_TIME -> my_time_t conversion.
48
47
  See comments for TIME_to_gmt_sec() for more info.
49
48
*/
50
49
typedef struct revtinfo
131
130
      offset - local time zone offset
132
131
 
133
132
  DESCRIPTION
134
 
    Convert my_time_t with offset to MYSQL_TIME struct. Differs from timesub
 
133
    Convert my_time_t with offset to DRIZZLE_TIME struct. Differs from timesub
135
134
    (from elsie code) because doesn't contain any leap correction and
136
135
    TM_GMTOFF and is_dst setting and contains some MySQL specific
137
136
    initialization. Funny but with removing of these we almost have
138
137
    glibc's offtime function.
139
138
*/
140
139
static void
141
 
sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset)
 
140
sec_to_TIME(DRIZZLE_TIME * tmp, my_time_t t, long offset)
142
141
{
143
142
  long days;
144
143
  long rem;
194
193
  tmp->month++;
195
194
  tmp->day= (uint)(days + 1);
196
195
 
197
 
  /* filling MySQL specific MYSQL_TIME members */
 
196
  /* filling MySQL specific DRIZZLE_TIME members */
198
197
  tmp->neg= 0; tmp->second_part= 0;
199
 
  tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
 
198
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
200
199
}
201
200
 
202
201
 
286
285
 
287
286
/*
288
287
  Converts time in my_time_t representation (seconds in UTC since Epoch) to
289
 
  broken down MYSQL_TIME representation in local time zone.
 
288
  broken down DRIZZLE_TIME representation in local time zone.
290
289
 
291
290
  SYNOPSIS
292
291
    gmt_sec_to_TIME()
301
300
    (60th and 61st second, look how we calculate them as "hit" in this
302
301
    function).
303
302
    Under realistic assumptions about frequency of transitions the same array
304
 
    can be used fot MYSQL_TIME -> my_time_t conversion. For this we need to
 
303
    can be used fot DRIZZLE_TIME -> my_time_t conversion. For this we need to
305
304
    implement tweaked binary search which will take into account that some
306
 
    MYSQL_TIME has two matching my_time_t ranges and some of them have none.
 
305
    DRIZZLE_TIME has two matching my_time_t ranges and some of them have none.
307
306
*/
308
307
static void
309
 
gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
 
308
gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
310
309
{
311
310
  const TRAN_TYPE_INFO *ttisp;
312
311
  const LS_INFO *lp;
408
407
}
409
408
 
410
409
/*
411
 
  Converts local time in broken down MYSQL_TIME representation to my_time_t
 
410
  Converts local time in broken down DRIZZLE_TIME representation to my_time_t
412
411
  representation.
413
412
 
414
413
  SYNOPSIS
450
449
 
451
450
    We use completely different approach. It is better since it is both
452
451
    faster than iterative implementations and fully determenistic. If you
453
 
    look at my_time_t to MYSQL_TIME conversion then you'll find that it consist
 
452
    look at my_time_t to DRIZZLE_TIME conversion then you'll find that it consist
454
453
    of two steps:
455
454
    The first is calculating shifted my_time_t value and the second - TIME
456
455
    calculation from shifted my_time_t value (well it is a bit simplified
480
479
    0 in case of error.
481
480
*/
482
481
static my_time_t
483
 
TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
 
482
TIME_to_gmt_sec(const DRIZZLE_TIME *t, const TIME_ZONE_INFO *sp,
484
483
                bool *in_dst_time_gap)
485
484
{
486
485
  my_time_t local_t;
603
602
{
604
603
public:
605
604
  Time_zone_system() {}                       /* Remove gcc warning */
606
 
  virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
 
605
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
607
606
                                    bool *in_dst_time_gap) const;
608
 
  virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
 
607
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
609
608
  virtual const String * get_name() const;
610
609
};
611
610
 
612
611
 
613
612
/*
614
 
  Converts local time in system time zone in MYSQL_TIME representation
 
613
  Converts local time in system time zone in DRIZZLE_TIME representation
615
614
  to its my_time_t representation.
616
615
 
617
616
  SYNOPSIS
618
617
    TIME_to_gmt_sec()
619
 
      t               - pointer to MYSQL_TIME structure with local time in
 
618
      t               - pointer to DRIZZLE_TIME structure with local time in
620
619
                        broken-down representation.
621
620
      in_dst_time_gap - pointer to bool which is set to true if datetime
622
621
                        value passed doesn't really exist (i.e. falls into
624
623
 
625
624
  DESCRIPTION
626
625
    This method uses system function (localtime_r()) for conversion
627
 
    local time in system time zone in MYSQL_TIME structure to its my_time_t
 
626
    local time in system time zone in DRIZZLE_TIME structure to its my_time_t
628
627
    representation. Unlike the same function for Time_zone_db class
629
628
    it it won't handle unnormalized input properly. Still it will
630
629
    return lowest possible my_time_t in case of ambiguity or if we
636
635
    Corresponding my_time_t value or 0 in case of error
637
636
*/
638
637
my_time_t
639
 
Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, bool *in_dst_time_gap) const
 
638
Time_zone_system::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
640
639
{
641
640
  long not_used;
642
641
  return my_system_gmt_sec(t, &not_used, in_dst_time_gap);
649
648
 
650
649
  SYNOPSIS
651
650
    gmt_sec_to_TIME()
652
 
      tmp - pointer to MYSQL_TIME structure to fill-in
 
651
      tmp - pointer to DRIZZLE_TIME structure to fill-in
653
652
      t   - my_time_t value to be converted
654
653
 
655
654
  NOTE
660
659
    the 1902 easily.
661
660
*/
662
661
void
663
 
Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
 
662
Time_zone_system::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
664
663
{
665
664
  struct tm tmp_tm;
666
665
  time_t tmp_t= (time_t)t;
667
666
 
668
667
  localtime_r(&tmp_t, &tmp_tm);
669
668
  localtime_to_TIME(tmp, &tmp_tm);
670
 
  tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
 
669
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
671
670
}
672
671
 
673
672
 
690
689
/*
691
690
  Instance of this class represents UTC time zone. It uses system gmtime_r
692
691
  function for conversions and is always available. It is used only for
693
 
  my_time_t -> MYSQL_TIME conversions in various UTC_...  functions, it is not
694
 
  intended for MYSQL_TIME -> my_time_t conversions and shouldn't be exposed to user.
 
692
  my_time_t -> DRIZZLE_TIME conversions in various UTC_...  functions, it is not
 
693
  intended for DRIZZLE_TIME -> my_time_t conversions and shouldn't be exposed to user.
695
694
*/
696
695
class Time_zone_utc : public Time_zone
697
696
{
698
697
public:
699
698
  Time_zone_utc() {}                          /* Remove gcc warning */
700
 
  virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
 
699
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
701
700
                                    bool *in_dst_time_gap) const;
702
 
  virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
 
701
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
703
702
  virtual const String * get_name() const;
704
703
};
705
704
 
706
705
 
707
706
/*
708
 
  Convert UTC time from MYSQL_TIME representation to its my_time_t representation.
 
707
  Convert UTC time from DRIZZLE_TIME representation to its my_time_t representation.
709
708
 
710
709
  SYNOPSIS
711
710
    TIME_to_gmt_sec()
712
 
      t               - pointer to MYSQL_TIME structure with local time
 
711
      t               - pointer to DRIZZLE_TIME structure with local time
713
712
                        in broken-down representation.
714
713
      in_dst_time_gap - pointer to bool which is set to true if datetime
715
714
                        value passed doesn't really exist (i.e. falls into
724
723
    0
725
724
*/
726
725
my_time_t
727
 
Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t __attribute__((unused)),
 
726
Time_zone_utc::TIME_to_gmt_sec(const DRIZZLE_TIME *t __attribute__((unused)),
728
727
                               bool *in_dst_time_gap __attribute__((unused))) const
729
728
{
730
729
  /* Should be never called */
739
738
 
740
739
  SYNOPSIS
741
740
    gmt_sec_to_TIME()
742
 
      tmp - pointer to MYSQL_TIME structure to fill-in
 
741
      tmp - pointer to DRIZZLE_TIME structure to fill-in
743
742
      t   - my_time_t value to be converted
744
743
 
745
744
  NOTE
746
745
    See note for apropriate Time_zone_system method.
747
746
*/
748
747
void
749
 
Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
 
748
Time_zone_utc::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
750
749
{
751
750
  struct tm tmp_tm;
752
751
  time_t tmp_t= (time_t)t;
753
752
  gmtime_r(&tmp_t, &tmp_tm);
754
753
  localtime_to_TIME(tmp, &tmp_tm);
755
 
  tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
 
754
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
756
755
}
757
756
 
758
757
 
787
786
{
788
787
public:
789
788
  Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
790
 
  virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
 
789
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
791
790
                                    bool *in_dst_time_gap) const;
792
 
  virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
 
791
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
793
792
  virtual const String * get_name() const;
794
793
private:
795
794
  TIME_ZONE_INFO *tz_info;
823
822
 
824
823
  SYNOPSIS
825
824
    TIME_to_gmt_sec()
826
 
      t               - pointer to MYSQL_TIME structure with local time
 
825
      t               - pointer to DRIZZLE_TIME structure with local time
827
826
                        in broken-down representation.
828
827
      in_dst_time_gap - pointer to bool which is set to true if datetime
829
828
                        value passed doesn't really exist (i.e. falls into
837
836
    Corresponding my_time_t value or 0 in case of error
838
837
*/
839
838
my_time_t
840
 
Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, bool *in_dst_time_gap) const
 
839
Time_zone_db::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
841
840
{
842
841
  return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
843
842
}
849
848
 
850
849
  SYNOPSIS
851
850
    gmt_sec_to_TIME()
852
 
      tmp - pointer to MYSQL_TIME structure to fill-in
 
851
      tmp - pointer to DRIZZLE_TIME structure to fill-in
853
852
      t   - my_time_t value to be converted
854
853
*/
855
854
void
856
 
Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
 
855
Time_zone_db::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
857
856
{
858
857
  ::gmt_sec_to_TIME(tmp, t, tz_info);
859
858
}
883
882
{
884
883
public:
885
884
  Time_zone_offset(long tz_offset_arg);
886
 
  virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
 
885
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
887
886
                                    bool *in_dst_time_gap) const;
888
 
  virtual void   gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
 
887
  virtual void   gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
889
888
  virtual const String * get_name() const;
890
889
  /*
891
890
    This have to be public because we want to be able to access it from
920
919
 
921
920
/*
922
921
  Converts local time in time zone described as offset from UTC
923
 
  from MYSQL_TIME representation to its my_time_t representation.
 
922
  from DRIZZLE_TIME representation to its my_time_t representation.
924
923
 
925
924
  SYNOPSIS
926
925
    TIME_to_gmt_sec()
927
 
      t               - pointer to MYSQL_TIME structure with local time
 
926
      t               - pointer to DRIZZLE_TIME structure with local time
928
927
                        in broken-down representation.
929
928
      in_dst_time_gap - pointer to bool which should be set to true if
930
929
                        datetime  value passed doesn't really exist
936
935
    Corresponding my_time_t value or 0 in case of error
937
936
*/
938
937
my_time_t
939
 
Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t,
 
938
Time_zone_offset::TIME_to_gmt_sec(const DRIZZLE_TIME *t,
940
939
                                  bool *in_dst_time_gap __attribute__((unused))) const
941
940
{
942
941
  my_time_t local_t;
982
981
 
983
982
  SYNOPSIS
984
983
    gmt_sec_to_TIME()
985
 
      tmp - pointer to MYSQL_TIME structure to fill-in
 
984
      tmp - pointer to DRIZZLE_TIME structure to fill-in
986
985
      t   - my_time_t value to be converted
987
986
*/
988
987
void
989
 
Time_zone_offset::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
 
988
Time_zone_offset::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
990
989
{
991
990
  sec_to_TIME(tmp, t, offset);
992
991
}