~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_time.cc

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 along with this program; if not, write to the Free Software
14
14
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include <my_time.h>
 
16
#include "mysys/mysys_priv.h"
 
17
 
 
18
#include "my_time.h"
 
19
 
17
20
#include <mystrings/m_string.h>
18
21
#include <mystrings/m_ctype.h>
 
22
#include <drizzled/util/test.h>
 
23
 
 
24
#include <stdio.h>
19
25
/* Windows version of localtime_r() is declared in my_ptrhead.h */
20
26
 
21
27
uint64_t log_10_int[20]=
39
45
unsigned char days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
40
46
 
41
47
/*
42
 
  Offset of system time zone from UTC in seconds used to speed up 
 
48
  Offset of system time zone from UTC in seconds used to speed up
43
49
  work of my_system_gmt_sec() function.
44
50
*/
45
51
static long my_time_zone=0;
195
201
       pos++)
196
202
    ;
197
203
 
198
 
  digits= (uint) (pos-str);
 
204
  digits= (uint32_t) (pos-str);
199
205
  start_loop= 0;                                /* Start of scan loop */
200
206
  date_len[format_position[0]]= 0;              /* Length of year field */
201
207
  if (pos == end || *pos == '.')
244
250
    2003-03-03 20:00:20 AM
245
251
    20:00:20.000000 AM 03-03-2000
246
252
  */
247
 
  i= cmax((uint) format_position[0], (uint) format_position[1]);
248
 
  set_if_bigger(i, (uint) format_position[2]);
 
253
  i= cmax((uint32_t) format_position[0], (uint32_t) format_position[1]);
 
254
  set_if_bigger(i, (uint32_t) format_position[2]);
249
255
  allow_space= ((1 << i) | (1 << format_position[6]));
250
256
  allow_space&= (1 | 2 | 4 | 8);
251
257
 
256
262
       i++)
257
263
  {
258
264
    const char *start= str;
259
 
    uint32_t tmp_value= (uint) (unsigned char) (*str++ - '0');
 
265
    uint32_t tmp_value= (uint32_t) (unsigned char) (*str++ - '0');
260
266
    while (str != end && my_isdigit(&my_charset_utf8_general_ci,str[0]) &&
261
267
           (!is_internal_format || --field_length))
262
268
    {
263
269
      tmp_value=tmp_value*10 + (uint32_t) (unsigned char) (*str - '0');
264
270
      str++;
265
271
    }
266
 
    date_len[i]= (uint) (str - start);
 
272
    date_len[i]= (uint32_t) (str - start);
267
273
    if (tmp_value > 999999)                     /* Impossible date part */
268
274
    {
269
275
      *was_cut= 1;
349
355
 
350
356
  if (!is_internal_format)
351
357
  {
352
 
    year_length= date_len[(uint) format_position[0]];
 
358
    year_length= date_len[(uint32_t) format_position[0]];
353
359
    if (!year_length)                           /* Year must be specified */
354
360
    {
355
361
      *was_cut= 1;
356
362
      return(DRIZZLE_TIMESTAMP_NONE);
357
363
    }
358
364
 
359
 
    l_time->year=               date[(uint) format_position[0]];
360
 
    l_time->month=              date[(uint) format_position[1]];
361
 
    l_time->day=                date[(uint) format_position[2]];
362
 
    l_time->hour=               date[(uint) format_position[3]];
363
 
    l_time->minute=             date[(uint) format_position[4]];
364
 
    l_time->second=             date[(uint) format_position[5]];
 
365
    l_time->year=               date[(uint32_t) format_position[0]];
 
366
    l_time->month=              date[(uint32_t) format_position[1]];
 
367
    l_time->day=                date[(uint32_t) format_position[2]];
 
368
    l_time->hour=               date[(uint32_t) format_position[3]];
 
369
    l_time->minute=             date[(uint32_t) format_position[4]];
 
370
    l_time->second=             date[(uint32_t) format_position[5]];
365
371
 
366
 
    frac_pos= (uint) format_position[6];
 
372
    frac_pos= (uint32_t) format_position[6];
367
373
    frac_len= date_len[frac_pos];
368
374
    if (frac_len < 6)
369
 
      date[frac_pos]*= (uint) log_10_int[6 - frac_len];
 
375
      date[frac_pos]*= (uint32_t) log_10_int[6 - frac_len];
370
376
    l_time->second_part= date[frac_pos];
371
377
 
372
378
    if (format_position[7] != (unsigned char) 255)
388
394
    l_time->minute=     date[4];
389
395
    l_time->second=     date[5];
390
396
    if (date_len[6] < 6)
391
 
      date[6]*= (uint) log_10_int[6 - date_len[6]];
 
397
      date[6]*= (uint32_t) log_10_int[6 - date_len[6]];
392
398
    l_time->second_part=date[6];
393
399
  }
394
400
  l_time->neg= 0;
514
520
    ;
515
521
 
516
522
  found_days=found_hours=0;
517
 
  if ((uint) (end-str) > 1 && str != end_of_days &&
 
523
  if ((uint32_t) (end-str) > 1 && str != end_of_days &&
518
524
      my_isdigit(&my_charset_utf8_general_ci, *str))
519
525
  {                                             /* Found days part */
520
526
    date[0]= (uint32_t) value;
571
577
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_utf8_general_ci,str[1]))
572
578
  {
573
579
    int field_length= 5;
574
 
    str++; value=(uint) (unsigned char) (*str - '0');
 
580
    str++; value=(uint32_t) (unsigned char) (*str - '0');
575
581
    while (++str != end && my_isdigit(&my_charset_utf8_general_ci, *str))
576
582
    {
577
583
      if (field_length-- > 0)
578
 
        value= value*10 + (uint) (unsigned char) (*str - '0');
 
584
        value= value*10 + (uint32_t) (unsigned char) (*str - '0');
579
585
    }
580
586
    if (field_length > 0)
581
587
      value*= (long) log_10_int[field_length];
585
591
  }
586
592
  else
587
593
    date[4]=0;
588
 
    
 
594
 
589
595
  /* Check for exponent part: E<gigit> | E<sign><digit> */
590
596
  /* (may occur as result of %g formatting of time value) */
591
597
  if ((end - str) > 1 &&
618
624
      date[2] > UINT_MAX || date[3] > UINT_MAX ||
619
625
      date[4] > UINT_MAX)
620
626
    return 1;
621
 
  
 
627
 
622
628
  l_time->year=         0;                      /* For protocol::store_time */
623
629
  l_time->month=        0;
624
630
  l_time->day=          date[0];
631
637
  /* Check if the value is valid and fits into DRIZZLE_TIME range */
632
638
  if (check_time_range(l_time, warning))
633
639
    return 1;
634
 
  
 
640
 
635
641
  /* Check if there is garbage at end of the DRIZZLE_TIME specification */
636
642
  if (str != end)
637
643
  {
666
672
    1        time value is invalid
667
673
*/
668
674
 
669
 
int check_time_range(DRIZZLE_TIME *my_time, int *warning) 
 
675
int check_time_range(DRIZZLE_TIME *my_time, int *warning)
670
676
{
671
677
  int64_t hour;
672
678
 
706
712
  localtime_r(&seconds,&tm_tmp);
707
713
  l_time= &tm_tmp;
708
714
  my_time_zone=         3600;           /* Comp. for -3600 in my_gmt_sec */
709
 
  my_time.year=         (uint) l_time->tm_year+1900;
710
 
  my_time.month=        (uint) l_time->tm_mon+1;
711
 
  my_time.day=          (uint) l_time->tm_mday;
712
 
  my_time.hour=         (uint) l_time->tm_hour;
713
 
  my_time.minute=       (uint) l_time->tm_min;
714
 
  my_time.second=       (uint) l_time->tm_sec;
 
715
  my_time.year=         (uint32_t) l_time->tm_year+1900;
 
716
  my_time.month=        (uint32_t) l_time->tm_mon+1;
 
717
  my_time.day=          (uint32_t) l_time->tm_mday;
 
718
  my_time.hour=         (uint32_t) l_time->tm_hour;
 
719
  my_time.minute=       (uint32_t) l_time->tm_min;
 
720
  my_time.second=       (uint32_t) l_time->tm_sec;
715
721
  my_system_gmt_sec(&my_time, &my_time_zone, &not_used); /* Init my_time_zone */
716
722
}
717
723
 
769
775
 
770
776
/*
771
777
  Convert time in DRIZZLE_TIME representation in system time zone to its
772
 
  my_time_t form (number of seconds in UTC since begginning of Unix Epoch).
 
778
  time_t form (number of seconds in UTC since begginning of Unix Epoch).
773
779
 
774
780
  SYNOPSIS
775
781
    my_system_gmt_sec()
779
785
      in_dst_time_gap - set to true if time falls into spring time-gap
780
786
 
781
787
  NOTES
782
 
    The idea is to cache the time zone offset from UTC (including daylight 
783
 
    saving time) for the next call to make things faster. But currently we 
784
 
    just calculate this offset during startup (by calling init_time() 
 
788
    The idea is to cache the time zone offset from UTC (including daylight
 
789
    saving time) for the next call to make things faster. But currently we
 
790
    just calculate this offset during startup (by calling init_time()
785
791
    function) and use it all the time.
786
792
    Time value provided should be legal time value (e.g. '2003-01-01 25:00:00'
787
793
    is not allowed).
789
795
  RETURN VALUE
790
796
    Time in UTC seconds since Unix Epoch representation.
791
797
*/
792
 
my_time_t
 
798
time_t
793
799
my_system_gmt_sec(const DRIZZLE_TIME *t_src, long *my_timezone,
794
800
                  bool *in_dst_time_gap)
795
801
{
863
869
  if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && (t->day > 4))
864
870
  {
865
871
    /*
866
 
      Below we will pass (uint) (t->day - shift) to calc_daynr.
 
872
      Below we will pass (uint32_t) (t->day - shift) to calc_daynr.
867
873
      As we don't want to get an overflow here, we will shift
868
874
      only safe dates. That's why we have (t->day > 4) above.
869
875
    */
900
906
  }
901
907
#endif
902
908
 
903
 
  tmp= (time_t) (((calc_daynr((uint) t->year, (uint) t->month, (uint) t->day) -
 
909
  tmp= (time_t) (((calc_daynr((uint32_t) t->year, (uint32_t) t->month, (uint32_t) t->day) -
904
910
                   (long) days_at_timestart)*86400L + (long) t->hour*3600L +
905
911
                  (long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
906
912
                 3600);
910
916
  l_time=&tm_tmp;
911
917
  for (loop=0;
912
918
       loop < 2 &&
913
 
         (t->hour != (uint) l_time->tm_hour ||
914
 
          t->minute != (uint) l_time->tm_min ||
915
 
          t->second != (uint) l_time->tm_sec);
 
919
         (t->hour != (uint32_t) l_time->tm_hour ||
 
920
          t->minute != (uint32_t) l_time->tm_min ||
 
921
          t->second != (uint32_t) l_time->tm_sec);
916
922
       loop++)
917
923
  {                                     /* One check should be enough ? */
918
924
    /* Get difference in days */
939
945
    general time correction like it happened for Africa/Monrovia time zone
940
946
    in year 1972).
941
947
  */
942
 
  if (loop == 2 && t->hour != (uint) l_time->tm_hour)
 
948
  if (loop == 2 && t->hour != (uint32_t) l_time->tm_hour)
943
949
  {
944
950
    int days= t->day - l_time->tm_mday;
945
951
    if (days < -1)
975
981
  if ((tmp < TIMESTAMP_MIN_VALUE) || (tmp > TIMESTAMP_MAX_VALUE))
976
982
    tmp= 0;
977
983
 
978
 
  return (my_time_t) tmp;
 
984
  return (time_t) tmp;
979
985
} /* my_system_gmt_sec */
980
986
 
981
987