1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: TimDate 4 -- 5 -- Project: Tools - General C objects. 6 -- System: Tim - Time and date manipulation. 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- Manage time and date. 12 -- 13 -- Date format: 14 -- Order: YMD, DMY or MDY 15 -- Separator: One character, 0 is no separator 16 -- Day leading 0: 0 is no, 1 is yes 17 -- Month leading 0: 0 is no, 1 is yes 18 -- Century: 0 is no, 1 is yes 19 -- 1st weekday: 0 is Sunday, 1 is Monday 20 -- 21 -- Time format: 22 -- 12 or 24 hour: 12 or 24 23 -- 12 hour suffix: Two characters, two blanks is no suffix 24 -- 24 hour suffix: Two characters, two blanks is no suffix 25 -- Separator: One character, 0 is no separator 26 -- Hour leading 0: 0 is no, 1 is yes 27 -- 28 -- Filename: TimDate.c 29 -- 30 -- Authors: Roger Larsson, Ulrika Bornetun 31 -- Creation date: 1990-11-30 32 -- 33 -- 34 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 35 -- All rights reserved 36 -- 37 -- Permission to use, copy, modify, and distribute this software and its 38 -- documentation for any purpose and without fee is hereby granted, 39 -- provided that the above copyright notice appear in all copies. Ulrika 40 -- Bornetun and Roger Larsson make no representations about the usability 41 -- of this software for any purpose. It is provided "as is" without express 42 -- or implied warranty. 43 ----------------------------------------------------------------------------*/ 44 45 /* SCCS module identifier. */ 46 static char SCCSID[] = "@(#) Module: TimDate.c, Version: 1.1, Date: 95/02/18 14:32:31"; 47 48 49 /*---------------------------------------------------------------------------- 50 -- Include files 51 ----------------------------------------------------------------------------*/ 52 53 #include <memory.h> 54 #include <stdio.h> 55 #include <string.h> 56 #include <time.h> 57 #include <sys/types.h> 58 #include <stdlib.h> 59 #include <ctype.h> 60 61 #include "System.h" 62 #include "TimDate.h" 63 64 65 /*---------------------------------------------------------------------------- 66 -- Macro definitions 67 ----------------------------------------------------------------------------*/ 68 69 70 /*---------------------------------------------------------------------------- 71 -- Type declarations 72 ----------------------------------------------------------------------------*/ 73 74 /* Order to use for year, month and day. */ 75 typedef enum { 76 DATE_MMDDYY, DATE_DDMMYY, DATE_YYMMDD 77 } DATE_ORDER; 78 79 /* Format used for dates. */ 80 typedef struct { 81 DATE_ORDER order; 82 char separator[ 2 ]; 83 Boolean day_leading_zero; 84 Boolean month_leading_zero; 85 Boolean include_century; 86 char ymd_format[ 50 ]; 87 char md_format[ 50 ]; 88 char d_format[ 50 ]; 89 int week_1st_day; 90 } DATE_FORMAT; 91 92 /* Format used for times. */ 93 typedef struct { 94 Boolean hour_12; 95 char hour_12_suffix[ 5 ]; 96 char hour_12_suffix_separator[ 2 ]; 97 char hour_24_suffix[ 5 ]; 98 char hour_24_suffix_separator[ 2 ]; 99 char separator[ 2 ]; 100 Boolean hour_leading_zero; 101 char hm_format[ 50 ]; 102 char m_format[ 50 ]; 103 } TIME_FORMAT; 104 105 106 /*---------------------------------------------------------------------------- 107 -- Global definitions 108 ----------------------------------------------------------------------------*/ 109 110 /* Date and time format. */ 111 static char date_format_string[ 50 ] = { 112 'Y', 'M', 'D', '-', '1', '1', '1', '1', '\0' }; 113 static char time_format_string[ 50 ] = { 114 '2', '4', ' ', ' ', ' ', ' ', ':', '0', '\0' }; 115 116 static DATE_FORMAT user_date_format = { 117 DATE_YYMMDD, { '-', '\0' }, True, True, True, 118 { '%','d','%','*','[','^','0','-','9',']','%','d','%','*','[','^','0','-', 119 '9',']','%','d','\0' }, 120 { '%','d','%','*','[','^','0','-','9',']','%','d','\0' }, 121 { '%','d','\0' }, 122 1 123 }; 124 125 static DATE_FORMAT iso_date_format = { 126 DATE_YYMMDD, { '-', '\0' }, True, True, True, 127 { '%','d','%','*','[','^','0','-','9',']','%','d','%','*','[','^','0','-', 128 '9',']','%','d','\0' }, 129 { '%','d','%','*','[','^','0','-','9',']','%','d','\0' }, 130 { '%','d','\0' }, 131 1 132 }; 133 134 static TIME_FORMAT user_time_format = { 135 False, 136 { '\0' }, { ' ', '\0' }, 137 { '\0' }, { ' ', '\0' }, 138 { ':', '\0' }, False, 139 { '%','d','%','*','[','^','0','-','9',']','%','d', '\0' }, 140 { '%','d','\0' } 141 }; 142 143 static TIME_FORMAT iso_time_format = { 144 False, 145 { '\0' }, { ' ', '\0' }, 146 { '\0' }, { ' ', '\0' }, 147 { ':', '\0' }, False, 148 { '%','d','%','*','[','^','0','-','9',']','%','d', '\0' }, 149 { '%','d','\0' } 150 }; 151 152 /* Number of days in the month. */ 153 static int days_in_month_leap_year[] = { 154 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 155 156 static int days_in_month[] = { 157 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 158 159 /* Offset of the days within the year (0 - 365). */ 160 static int day_offset[] = { 161 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; 162 163 static int day_offset_leap_year[] = { 164 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; 165 166 /* Week number offsets 1970-2070 (not nice but it works). */ 167 static UINT8 mon_week_offsets[] = { 168 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 169 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 170 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 171 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 172 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 173 1, 174 }; 175 176 static UINT8 sun_week_offsets[] = { 177 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 178 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 179 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 180 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 181 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 182 1, 183 }; 184 185 /* Use the standard UNIX week numbers. */ 186 static unix_week_no = False; 187 188 189 /*---------------------------------------------------------------------------- 190 -- Function prototypes 191 ----------------------------------------------------------------------------*/ 192 193 static struct tm 194 *convertToLocalStruct( TIM_TIME_REF time, 195 struct tm *container ); 196 197 static struct tm 198 *convertToStruct( TIM_TIME_REF time, 199 struct tm *container ); 200 201 static int 202 dayNumberInYear( int year, 203 int month, 204 int day ); 205 206 static int 207 daysInYear( int year ); 208 209 static void 210 formatDate( DATE_FORMAT *date_format, 211 TIM_TIME_REF time, 212 char *buffer, 213 int buffer_size ); 214 215 static void 216 formatFullDate( DATE_FORMAT *date_format, 217 TIM_TIME_REF time, 218 char *buffer, 219 int buffer_size ); 220 221 static void 222 formatTime( TIME_FORMAT *time_format, 223 TIM_TIME_REF time, 224 char *buffer, 225 int buffer_size ); 226 227 static TIM_STATUS_TYPE 228 isTimeOk( int year, 229 int month, 230 int day, 231 int hour, 232 int minute, 233 int second ); 234 235 static TIM_STATUS_TYPE 236 makeDateFromString( DATE_FORMAT *date_format, 237 TIM_TIME_REF *time, 238 char *string ); 239 240 static TIM_STATUS_TYPE 241 makeTimeFromString( TIME_FORMAT *time_format, 242 TIM_TIME_REF *time, 243 char *string ); 244 245 static int 246 noCaseStrcmp( char *buffer1, 247 char *buffer2 ); 248 249 static time_t 250 secondsSince1970( struct tm *time_ref ); 251 252 253 /*---------------------------------------------------------------------------- 254 -- Functions 255 ----------------------------------------------------------------------------*/ 256 257 void TimAddDays(TIM_TIME_REF * time,int days)258 TimAddDays( TIM_TIME_REF *time, int days ) 259 { 260 261 /* Code. */ 262 263 *time = *time + (days * 24 * 60 * 60); 264 265 } /* TimAddDays */ 266 267 268 /*----------------------------------------------------------------------*/ 269 270 void TimAddHours(TIM_TIME_REF * time,int hours)271 TimAddHours( TIM_TIME_REF *time, int hours ) 272 { 273 274 /* Code. */ 275 276 *time = *time + (hours * 60 * 60); 277 278 279 return; 280 281 } /* TimAddHours */ 282 283 284 /*----------------------------------------------------------------------*/ 285 286 void TimAddMinutes(TIM_TIME_REF * time,int minutes)287 TimAddMinutes( TIM_TIME_REF *time, int minutes ) 288 { 289 290 /* Code. */ 291 292 *time = *time + (minutes * 60); 293 294 295 return; 296 297 } /* TimAddMinutes */ 298 299 300 /*----------------------------------------------------------------------*/ 301 302 void TimAddMonths(TIM_TIME_REF * time,int months)303 TimAddMonths( TIM_TIME_REF *time, int months ) 304 { 305 306 /* Variables. */ 307 int add_months; 308 int add_year; 309 time_t new_time; 310 struct tm *time_struct; 311 struct tm time_struct_obj; 312 313 314 /* Code. */ 315 316 time_struct = convertToStruct( *time, &time_struct_obj ); 317 318 add_year = abs( months ) / 12; 319 add_months = abs( months ) % 12; 320 321 if( months < 0 ) { 322 time_struct -> tm_year = time_struct -> tm_year - add_year; 323 time_struct -> tm_mon = time_struct -> tm_mon - add_months; 324 } else { 325 time_struct -> tm_year = time_struct -> tm_year + add_year; 326 time_struct -> tm_mon = time_struct -> tm_mon + add_months; 327 } 328 329 if( time_struct -> tm_mon > 11 ) { 330 time_struct -> tm_year = time_struct -> tm_year + 1; 331 time_struct -> tm_mon = time_struct -> tm_mon - 12; 332 } 333 334 if( time_struct -> tm_mon < 0 ) { 335 time_struct -> tm_year = time_struct -> tm_year - 1; 336 time_struct -> tm_mon = time_struct -> tm_mon + 12; 337 } 338 339 time_struct -> tm_yday = dayNumberInYear( 340 time_struct -> tm_year, 341 time_struct -> tm_mon + 1, 342 time_struct -> tm_mday ) - 1; 343 344 new_time = (TIM_TIME_REF) secondsSince1970( time_struct ); 345 346 *time = new_time; 347 348 349 return; 350 351 } /* TimAddMonths */ 352 353 354 /*----------------------------------------------------------------------*/ 355 356 void TimAddSeconds(TIM_TIME_REF * time,int seconds)357 TimAddSeconds( TIM_TIME_REF *time, int seconds ) 358 { 359 360 /* Code. */ 361 362 *time = *time + seconds; 363 364 365 return; 366 367 } /* TimAddSeconds */ 368 369 370 /*----------------------------------------------------------------------*/ 371 372 TIM_TIME_REF TimAddTime(TIM_TIME_REF time,TIM_TIME_REF to_time)373 TimAddTime( TIM_TIME_REF time, 374 TIM_TIME_REF to_time ) 375 { 376 377 /* Code. */ 378 379 return( time + to_time ); 380 381 } /* TimAdd */ 382 383 384 /*----------------------------------------------------------------------*/ 385 386 void TimAddYears(TIM_TIME_REF * time,int years)387 TimAddYears( TIM_TIME_REF *time, int years ) 388 { 389 390 /* Variables. */ 391 time_t new_time; 392 struct tm *time_struct; 393 struct tm time_struct_obj; 394 395 396 /* Code. */ 397 398 time_struct = convertToStruct( *time, &time_struct_obj ); 399 400 time_struct -> tm_year = time_struct -> tm_year + years; 401 time_struct -> tm_yday = dayNumberInYear( 402 time_struct -> tm_year, 403 time_struct -> tm_mon + 1, 404 time_struct -> tm_mday ) - 1; 405 406 new_time = (TIM_TIME_REF) secondsSince1970( time_struct ); 407 408 if( new_time >= 0 ) 409 *time = new_time; 410 411 412 return; 413 414 } /* TimAddYears */ 415 416 417 /*----------------------------------------------------------------------*/ 418 419 int TimDaysInMonth(TIM_TIME_REF time)420 TimDaysInMonth( TIM_TIME_REF time ) 421 { 422 423 /* Variables. */ 424 struct tm *time_struct; 425 struct tm time_struct_obj; 426 427 428 /* Code. */ 429 430 time_struct = convertToStruct( time, &time_struct_obj ); 431 432 if( TimIsLeapYear( time ) == TIM_YES ) 433 return( days_in_month_leap_year[ time_struct -> tm_mon ] ); 434 435 436 return( days_in_month[ time_struct -> tm_mon ] ); 437 438 } /* TimDaysInMonth */ 439 440 441 /*----------------------------------------------------------------------*/ 442 443 int TimDaysInYear(TIM_TIME_REF time)444 TimDaysInYear( TIM_TIME_REF time ) 445 { 446 447 /* Code. */ 448 449 if( TimIsLeapYear( time ) == TIM_YES ) 450 return( 366 ); 451 452 453 return( 365 ); 454 455 } /* TimDaysInYear */ 456 457 458 /*----------------------------------------------------------------------*/ 459 460 TIM_STATUS_TYPE TimDelta(TIM_TIME_REF time1,TIM_TIME_REF time2,TIM_DELTA_TYPE * delta)461 TimDelta( TIM_TIME_REF time1, 462 TIM_TIME_REF time2, 463 TIM_DELTA_TYPE *delta ) 464 { 465 466 /* Variables. */ 467 TIM_TIME_REF temp_time; 468 469 470 /* Code. */ 471 472 if( time1 > time2 ) { 473 temp_time = time1; 474 time1 = time2; 475 time2 = temp_time; 476 } 477 478 delta -> seconds = ((int) time2) - ((int) time1); 479 delta -> minutes = delta -> seconds / 60; 480 delta -> hours = delta -> seconds / (60 * 60); 481 delta -> days = delta -> seconds / (60 * 60 * 24); 482 delta -> weeks = delta -> seconds / (60 * 60 * 24 * 7); 483 484 485 return( TIM_OK ); 486 487 } /* TimDelta */ 488 489 490 /*----------------------------------------------------------------------*/ 491 492 void TimFormatDate(TIM_TIME_REF time,char * buffer,int buffer_size)493 TimFormatDate( TIM_TIME_REF time, 494 char *buffer, 495 int buffer_size ) 496 { 497 498 /* Code. */ 499 500 formatDate( &user_date_format, time, buffer, buffer_size ); 501 502 503 return; 504 505 } /* TimFormatDate */ 506 507 508 /*----------------------------------------------------------------------*/ 509 510 void TimFormatIsoDate(TIM_TIME_REF time,char * buffer,int buffer_size)511 TimFormatIsoDate( TIM_TIME_REF time, 512 char *buffer, 513 int buffer_size ) 514 { 515 516 /* Code. */ 517 518 formatDate( &iso_date_format, time, buffer, buffer_size ); 519 520 521 return; 522 523 } /* TimFormatIsoDate */ 524 525 526 /*----------------------------------------------------------------------*/ 527 528 void TimFormatFullDate(TIM_TIME_REF time,char * buffer,int buffer_size)529 TimFormatFullDate( TIM_TIME_REF time, 530 char *buffer, 531 int buffer_size ) 532 { 533 534 /* Code. */ 535 536 formatFullDate( &user_date_format, time, buffer, buffer_size ); 537 538 539 return; 540 541 } /* TimFormatFullDate */ 542 543 544 /*----------------------------------------------------------------------*/ 545 546 void TimFormatFullIsoDate(TIM_TIME_REF time,char * buffer,int buffer_size)547 TimFormatFullIsoDate( TIM_TIME_REF time, 548 char *buffer, 549 int buffer_size ) 550 { 551 552 /* Code. */ 553 554 formatFullDate( &iso_date_format, time, buffer, buffer_size ); 555 556 557 return; 558 559 } /* TimFormatFullIsoDate */ 560 561 562 /*----------------------------------------------------------------------*/ 563 564 void TimFormatStrTime(TIM_TIME_REF time,char * format,char * buffer,int buffer_size)565 TimFormatStrTime( TIM_TIME_REF time, 566 char *format, 567 char *buffer, 568 int buffer_size ) 569 { 570 571 /* Variables. */ 572 int size; 573 struct tm *time_struct; 574 struct tm time_struct_obj; 575 576 577 /* Code. */ 578 579 time_struct = convertToStruct( time, &time_struct_obj ); 580 581 size = strftime( buffer, buffer_size, format, time_struct ); 582 583 if( size == 0 ) 584 *buffer = '\0'; 585 586 587 return; 588 589 } /* TimFormatStrTime */ 590 591 592 /*----------------------------------------------------------------------*/ 593 594 void TimFormatTime(TIM_TIME_REF time,char * buffer,int buffer_size)595 TimFormatTime( TIM_TIME_REF time, 596 char *buffer, 597 int buffer_size ) 598 { 599 600 /* Code. */ 601 602 formatTime( &user_time_format, time, buffer, buffer_size ); 603 604 605 return; 606 607 } /* TimFormatTime */ 608 609 610 /*----------------------------------------------------------------------*/ 611 612 void TimFormatIsoTime(TIM_TIME_REF time,char * buffer,int buffer_size)613 TimFormatIsoTime( TIM_TIME_REF time, 614 char *buffer, 615 int buffer_size ) 616 { 617 618 /* Code. */ 619 620 formatTime( &iso_time_format, time, buffer, buffer_size ); 621 622 623 return; 624 625 } /* TimFormatIsoTime */ 626 627 628 /*----------------------------------------------------------------------*/ 629 630 int TimHour(TIM_TIME_REF time)631 TimHour( TIM_TIME_REF time ) 632 { 633 634 /* Variables. */ 635 struct tm *time_struct; 636 struct tm time_struct_obj; 637 638 639 /* Code. */ 640 641 time_struct = convertToStruct( time, &time_struct_obj ); 642 643 644 return( time_struct -> tm_hour ); 645 646 } /* TimHour */ 647 648 649 /*----------------------------------------------------------------------*/ 650 651 int TimIndexOfDay(TIM_TIME_REF time)652 TimIndexOfDay( TIM_TIME_REF time ) 653 { 654 655 /* Variables. */ 656 struct tm *time_struct; 657 struct tm time_struct_obj; 658 659 660 /* Code. */ 661 662 time_struct = convertToStruct( time, &time_struct_obj ); 663 664 665 return( time_struct -> tm_mday ); 666 667 } /* TimIndexOfDay */ 668 669 670 /*----------------------------------------------------------------------*/ 671 672 int TimIndexOfDayInIsoWeek(TIM_TIME_REF time)673 TimIndexOfDayInIsoWeek( TIM_TIME_REF time ) 674 { 675 676 /* Variables. */ 677 struct tm *time_struct; 678 struct tm time_struct_obj; 679 680 681 /* Code. */ 682 683 time_struct = convertToStruct( time, &time_struct_obj ); 684 685 if( time_struct -> tm_wday == 0 ) 686 return( time_struct -> tm_wday + 7 ); 687 688 689 return( time_struct -> tm_wday ); 690 691 } /* TimIndexOfDayInIsoWeek */ 692 693 694 /*----------------------------------------------------------------------*/ 695 696 int TimIndexOfDayInWeek(TIM_TIME_REF time)697 TimIndexOfDayInWeek( TIM_TIME_REF time ) 698 { 699 700 /* Variables. */ 701 struct tm *time_struct; 702 struct tm time_struct_obj; 703 704 705 /* Code. */ 706 707 time_struct = convertToStruct( time, &time_struct_obj ); 708 709 switch( user_date_format.week_1st_day ) { 710 711 case 0: 712 return( time_struct -> tm_wday + 1 ); 713 714 case 1: 715 default: 716 if( time_struct -> tm_wday == 0 ) 717 return( time_struct -> tm_wday + 7 ); 718 else 719 return( time_struct -> tm_wday ); 720 721 } /* switch */ 722 723 } /* TimIndexOfDayInWeek */ 724 725 726 /*----------------------------------------------------------------------*/ 727 728 int TimIndexOfFirstDayInWeek()729 TimIndexOfFirstDayInWeek() 730 { 731 732 /* Code. */ 733 734 735 return( user_date_format.week_1st_day ); 736 737 } /* TimIndexOfFirstDayInWeek */ 738 739 740 /*----------------------------------------------------------------------*/ 741 742 int TimIndexOfDayInYear(TIM_TIME_REF time)743 TimIndexOfDayInYear( TIM_TIME_REF time ) 744 { 745 746 /* Variables. */ 747 struct tm *time_struct; 748 struct tm time_struct_obj; 749 750 751 /* Code. */ 752 753 time_struct = convertToStruct( time, &time_struct_obj ); 754 755 756 return( time_struct -> tm_yday + 1 ); 757 758 } /* TimIndexOfDayInYear */ 759 760 761 /*----------------------------------------------------------------------*/ 762 763 int TimIndexOfMonth(TIM_TIME_REF time)764 TimIndexOfMonth( TIM_TIME_REF time ) 765 { 766 767 /* Variables. */ 768 struct tm *time_struct; 769 struct tm time_struct_obj; 770 771 772 /* Code. */ 773 774 time_struct = convertToStruct( time, &time_struct_obj ); 775 776 777 return( time_struct -> tm_mon + 1 ); 778 779 } /* TimIndexOfMonth */ 780 781 782 /*----------------------------------------------------------------------*/ 783 784 int TimIndexOfIsoWeek(TIM_TIME_REF time)785 TimIndexOfIsoWeek( TIM_TIME_REF time ) 786 { 787 788 /* Variables. */ 789 int week_no; 790 int year; 791 char buffer[ 10 ]; 792 struct tm *time_struct; 793 struct tm time_struct_obj; 794 795 796 /* Code. */ 797 798 time_struct = convertToStruct( time, &time_struct_obj ); 799 800 strftime( buffer, sizeof( buffer ), "%W", time_struct ); 801 802 week_no = atoi( buffer ) + 1; 803 year = time_struct -> tm_year + 1900; 804 805 if( week_no > 1 && year >= 1970 && year <= 2070 && ! unix_week_no ) 806 week_no = week_no - (int) mon_week_offsets[ year - 1970 ]; 807 808 809 return( week_no ); 810 811 } /* TimIndexOfIsoWeek */ 812 813 814 /*----------------------------------------------------------------------*/ 815 816 int TimIndexOfWeek(TIM_TIME_REF time)817 TimIndexOfWeek( TIM_TIME_REF time ) 818 { 819 820 /* Variables. */ 821 int week_no; 822 int year; 823 char buffer[ 10 ]; 824 struct tm *time_struct; 825 struct tm time_struct_obj; 826 827 828 /* Code. */ 829 830 time_struct = convertToStruct( time, &time_struct_obj ); 831 832 switch( user_date_format.week_1st_day ) { 833 case 0: 834 strftime( buffer, sizeof( buffer ), "%U", time_struct ); 835 break; 836 837 case 1: 838 default: 839 strftime( buffer, sizeof( buffer ), "%W", time_struct ); 840 break; 841 } 842 843 week_no = atoi( buffer ) + 1; 844 year = time_struct -> tm_year + 1900; 845 846 switch( user_date_format.week_1st_day ) { 847 case 0: 848 if( week_no > 1 && year >= 1970 && year <= 2070 && ! unix_week_no ) 849 week_no = week_no - (int) sun_week_offsets[ year - 1970 ]; 850 break; 851 852 case 1: 853 default: 854 if( week_no > 1 && year >= 1970 && year <= 2070 && ! unix_week_no ) 855 week_no = week_no - (int) mon_week_offsets[ year - 1970 ]; 856 break; 857 } 858 859 860 return( week_no ); 861 862 } /* TimIndexOfWeek */ 863 864 865 /*----------------------------------------------------------------------*/ 866 867 int TimIndexOfYear(TIM_TIME_REF time)868 TimIndexOfYear( TIM_TIME_REF time ) 869 { 870 871 /* Variables. */ 872 struct tm *time_struct; 873 struct tm time_struct_obj; 874 875 876 /* Code. */ 877 878 time_struct = convertToStruct( time, &time_struct_obj ); 879 880 881 return( time_struct -> tm_year + 1900 ); 882 883 } /* TimIndexOfYear */ 884 885 886 /*----------------------------------------------------------------------*/ 887 888 TIM_STATUS_TYPE TimInitializeFormat(char * date_format_str,char * time_format_str)889 TimInitializeFormat( char *date_format_str, 890 char *time_format_str ) 891 { 892 893 /* Variables. */ 894 char day_format[ 50 ]; 895 char hour_format[ 50 ]; 896 char minute_format[ 50 ]; 897 char month_format[ 50 ]; 898 char sep_format[ 50 ]; 899 char suffix_format[ 50 ]; 900 char year_format[ 50 ]; 901 DATE_FORMAT new_date_format; 902 TIME_FORMAT new_time_format; 903 904 905 /* Code. */ 906 907 /* Correct length of the format strings? */ 908 if( strlen( date_format_str ) != 8 ) 909 return( TIM_ERROR ); 910 911 if( strlen( time_format_str ) != 8 ) 912 return( TIM_ERROR ); 913 914 915 /* Date format. */ 916 917 /* Date order. */ 918 if( strncmp( &date_format_str[ 0 ], "MDY", 3 ) == 0 ) 919 new_date_format.order = DATE_MMDDYY; 920 else if( strncmp( &date_format_str[ 0 ], "DMY", 3 ) == 0 ) 921 new_date_format.order = DATE_DDMMYY; 922 else if( strncmp( &date_format_str[ 0 ], "YMD", 3 ) == 0 ) 923 new_date_format.order = DATE_YYMMDD; 924 else 925 return( TIM_ERROR ); 926 927 /* Separator. */ 928 if( date_format_str[ 3 ] == '0' ) 929 strcpy( new_date_format.separator, "" ); 930 else if( ! isdigit( date_format_str[ 3 ] ) ) { 931 new_date_format.separator[ 0 ] = date_format_str[ 3 ]; 932 new_date_format.separator[ 1 ] = '\0'; 933 } else 934 return( TIM_ERROR ); 935 936 /* Day leading zero. */ 937 if( date_format_str[ 4 ] == '1' ) 938 new_date_format.day_leading_zero = True; 939 else 940 new_date_format.day_leading_zero = False; 941 942 /* Month leading zero. */ 943 if( date_format_str[ 5 ] == '1' ) 944 new_date_format.month_leading_zero = True; 945 else 946 new_date_format.month_leading_zero = False; 947 948 /* Include century. */ 949 if( date_format_str[ 6 ] == '1' ) 950 new_date_format.include_century = True; 951 else 952 new_date_format.include_century = False; 953 954 /* First day in week. */ 955 if( date_format_str[ 7 ] == '0' ) 956 new_date_format.week_1st_day = 0; 957 else 958 new_date_format.week_1st_day = 1; 959 960 961 /* Time format. */ 962 963 /* 12/24 hour time. */ 964 if( strncmp( &time_format_str[ 0 ], "12", 2 ) == 0 ) 965 new_time_format.hour_12 = True; 966 else if( strncmp( &time_format_str[ 0 ], "24", 2 ) == 0 ) 967 new_time_format.hour_12 = False; 968 else 969 return( TIM_ERROR ); 970 971 /* 12 hour suffix. */ 972 if( strncmp( &time_format_str[ 2 ], " ", 2 ) == 0 ) { 973 if( new_time_format.hour_12 ) { 974 strncpy( new_time_format.hour_12_suffix, "am", 2 ); 975 new_time_format.hour_12_suffix[ 2 ] = '\0'; 976 strcpy( new_time_format.hour_12_suffix_separator, " " ); 977 } else { 978 new_time_format.hour_12_suffix[ 0 ] = '\0'; 979 strcpy( new_time_format.hour_12_suffix_separator, "" ); 980 } 981 } else { 982 strncpy( new_time_format.hour_12_suffix, &time_format_str[ 2 ], 2 ); 983 new_time_format.hour_12_suffix[ 2 ] = '\0'; 984 strcpy( new_time_format.hour_12_suffix_separator, " " ); 985 } 986 987 /* 24 hour suffix. */ 988 if( strncmp( &time_format_str[ 4 ], " ", 2 ) == 0 ) { 989 if( new_time_format.hour_12 ) { 990 strncpy( new_time_format.hour_24_suffix, "pm", 2 ); 991 new_time_format.hour_24_suffix[ 2 ] = '\0'; 992 strcpy( new_time_format.hour_24_suffix_separator, " " ); 993 } else { 994 new_time_format.hour_24_suffix[ 0 ] = '\0'; 995 strcpy( new_time_format.hour_24_suffix_separator, "" ); 996 } 997 } else { 998 strncpy( new_time_format.hour_24_suffix, &time_format_str[ 4 ], 2 ); 999 new_time_format.hour_24_suffix[ 2 ] = '\0'; 1000 strcpy( new_time_format.hour_24_suffix_separator, " " ); 1001 } 1002 1003 /* Separator. */ 1004 if( time_format_str[ 6 ] == '0' ) { 1005 strcpy( new_time_format.separator, "" ); 1006 } else if( ! isdigit( time_format_str[ 6 ] ) ) { 1007 new_time_format.separator[ 0 ] = time_format_str[ 6 ]; 1008 new_time_format.separator[ 1 ] = '\0'; 1009 } else 1010 return( TIM_ERROR ); 1011 1012 /* Hour leading zero. */ 1013 if( time_format_str[ 7 ] == '1' ) 1014 new_time_format.hour_leading_zero = True; 1015 else 1016 new_time_format.hour_leading_zero = False; 1017 1018 1019 /* Store the result. */ 1020 memcpy( (void *) &user_date_format, (void *) &new_date_format, 1021 sizeof( DATE_FORMAT ) ); 1022 1023 memcpy( (void *) &user_time_format, (void *) &new_time_format, 1024 sizeof( TIME_FORMAT ) ); 1025 1026 1027 /* Read dates. */ 1028 1029 /* Year format? */ 1030 if( user_date_format.separator[ 0 ] == '\0' ) { 1031 if( user_date_format.include_century ) 1032 strcpy( year_format, "%4d" ); 1033 else 1034 strcpy( year_format, "%2d" ); 1035 } else 1036 strcpy( year_format, "%d" ); 1037 1038 /* Month format? */ 1039 if( user_date_format.separator[ 0 ] == '\0' ) { 1040 if( user_date_format.month_leading_zero ) 1041 strcpy( month_format, "%2d" ); 1042 else 1043 strcpy( month_format, "%1d" ); 1044 } else 1045 strcpy( month_format, "%d" ); 1046 1047 /* Day format? */ 1048 if( user_date_format.separator[ 0 ] == '\0' ) { 1049 if( user_date_format.day_leading_zero ) 1050 strcpy( day_format, "%2d" ); 1051 else 1052 strcpy( day_format, "%1d" ); 1053 } else 1054 strcpy( day_format, "%d" ); 1055 1056 /* Separator format? */ 1057 if( user_date_format.separator[ 0 ] != '\0' ) 1058 strcpy( sep_format, "%*[^0-9]" ); 1059 else 1060 sep_format[ 0 ] = '\0'; 1061 1062 /* MMDDYY format? */ 1063 if( user_date_format.order == DATE_MMDDYY ) { 1064 sprintf( user_date_format.ymd_format, "%s%s%s%s%s", 1065 month_format, sep_format, day_format, sep_format, year_format ); 1066 sprintf( user_date_format.md_format, "%s%s%s", 1067 month_format, sep_format, day_format ); 1068 sprintf( user_date_format.d_format, "%s", 1069 day_format ); 1070 } 1071 1072 /* DDMMYY format? */ 1073 if( user_date_format.order == DATE_DDMMYY ) { 1074 sprintf( user_date_format.ymd_format, "%s%s%s%s%s", 1075 day_format, sep_format, month_format, sep_format, year_format ); 1076 sprintf( user_date_format.md_format, "%s%s%s", 1077 day_format, sep_format, month_format ); 1078 sprintf( user_date_format.d_format, "%s", 1079 day_format ); 1080 } 1081 1082 /* YYMMDD format? */ 1083 if( user_date_format.order == DATE_YYMMDD ) { 1084 sprintf( user_date_format.ymd_format, "%s%s%s%s%s", 1085 year_format, sep_format, month_format, sep_format, day_format ); 1086 sprintf( user_date_format.md_format, "%s%s%s", 1087 month_format, sep_format, day_format ); 1088 sprintf( user_date_format.d_format, "%s", 1089 day_format ); 1090 } 1091 1092 1093 /* Read times. */ 1094 1095 /* Hour format? */ 1096 if( user_time_format.separator[ 0 ] == '\0' ) { 1097 if( user_time_format.hour_leading_zero ) 1098 strcpy( hour_format, "%2d" ); 1099 else 1100 strcpy( hour_format, "%1d" ); 1101 } else 1102 strcpy( hour_format, "%d" ); 1103 1104 /* Minute format? */ 1105 strcpy( minute_format, "%2d" ); 1106 1107 /* Separator format? */ 1108 if( user_time_format.separator[ 0 ] != '\0' ) 1109 strcpy( sep_format, "%*[^0-9]" ); 1110 else 1111 sep_format[ 0 ] = '\0'; 1112 1113 /* Suffix format. */ 1114 if( user_time_format.hour_12 ) 1115 strcpy( suffix_format, "%s" ); 1116 else 1117 suffix_format[ 0 ] = '\0'; 1118 1119 /* Time formats. */ 1120 sprintf( user_time_format.hm_format, "%s%s%s%s", 1121 hour_format, sep_format, minute_format, suffix_format ); 1122 sprintf( user_time_format.m_format, "%s%s", 1123 minute_format, suffix_format ); 1124 1125 1126 /* Save the date and time formats. */ 1127 strcpy( date_format_string, date_format_str ); 1128 strcpy( time_format_string, time_format_str ); 1129 1130 1131 return( TIM_OK ); 1132 1133 } /* TimInitializeFormat */ 1134 1135 1136 /*----------------------------------------------------------------------*/ 1137 1138 TIM_STATUS_TYPE TimIsLeapYear(TIM_TIME_REF time)1139 TimIsLeapYear( TIM_TIME_REF time ) 1140 { 1141 1142 /* Variables. */ 1143 struct tm *time_struct; 1144 struct tm time_struct_obj; 1145 1146 1147 /* Code. */ 1148 1149 time_struct = convertToStruct( time, &time_struct_obj ); 1150 1151 if( daysInYear( time_struct -> tm_year ) == 366 ) 1152 return( TIM_YES ); 1153 1154 1155 return( TIM_NO ); 1156 1157 } /* TimIsLeapYear */ 1158 1159 1160 /*----------------------------------------------------------------------*/ 1161 1162 TIM_STATUS_TYPE TimIsSameDate(TIM_TIME_REF time1,TIM_TIME_REF time2)1163 TimIsSameDate( TIM_TIME_REF time1, 1164 TIM_TIME_REF time2 ) 1165 { 1166 1167 /* Code. */ 1168 1169 if( TimIndexOfYear( time1 ) == TimIndexOfYear( time2 ) && 1170 TimIndexOfMonth( time1 ) == TimIndexOfMonth( time2 ) && 1171 TimIndexOfDay( time1 ) == TimIndexOfDay( time2 ) ) 1172 return( TIM_YES ); 1173 1174 1175 return( TIM_NO ); 1176 1177 } /* TimIsSameDate */ 1178 1179 1180 /*----------------------------------------------------------------------*/ 1181 1182 TIM_TIME_REF TimLocalTime(TIM_TIME_REF time)1183 TimLocalTime( TIM_TIME_REF time ) 1184 { 1185 1186 /* Variables. */ 1187 time_t new_time; 1188 struct tm *time_struct; 1189 struct tm time_struct_obj; 1190 1191 1192 /* Code. */ 1193 1194 time_struct = convertToLocalStruct( time, &time_struct_obj ); 1195 1196 new_time = secondsSince1970( time_struct ); 1197 1198 1199 return( (TIM_TIME_REF) new_time ); 1200 1201 } /* TimLocalTime */ 1202 1203 1204 /*----------------------------------------------------------------------*/ 1205 1206 TIM_TIME_REF TimMakeTime(int year,int month,int day,int hour,int minute,int second)1207 TimMakeTime( int year, 1208 int month, 1209 int day, 1210 int hour, 1211 int minute, 1212 int second ) 1213 { 1214 1215 /* Variables. */ 1216 time_t new_time; 1217 time_t now; 1218 struct tm *time_struct; 1219 struct tm time_struct_obj; 1220 1221 1222 /* Code. */ 1223 1224 now = time( NULL ); 1225 1226 time_struct = convertToStruct( now, &time_struct_obj ); 1227 1228 if( year != TIM_NOW ) 1229 time_struct -> tm_year = year - 1900; 1230 1231 if( month != TIM_NOW ) 1232 time_struct -> tm_mon = month - 1; 1233 1234 if( day != TIM_NOW ) 1235 time_struct -> tm_mday = day; 1236 1237 if( hour != TIM_NOW ) 1238 time_struct -> tm_hour = hour; 1239 1240 if( minute != TIM_NOW ) 1241 time_struct -> tm_min = minute; 1242 1243 if( second != TIM_NOW ) 1244 time_struct -> tm_sec = second; 1245 1246 time_struct -> tm_yday = dayNumberInYear( 1247 time_struct -> tm_year, 1248 time_struct -> tm_mon + 1, 1249 time_struct -> tm_mday ) - 1; 1250 1251 new_time = (TIM_TIME_REF) secondsSince1970( time_struct ); 1252 1253 1254 return( new_time ); 1255 1256 } /* TimMakeTime */ 1257 1258 1259 /*----------------------------------------------------------------------*/ 1260 1261 TIM_STATUS_TYPE TimMakeDateFromString(TIM_TIME_REF * time,char * string)1262 TimMakeDateFromString( TIM_TIME_REF *time, 1263 char *string ) 1264 { 1265 1266 /* Variables. */ 1267 TIM_STATUS_TYPE status; 1268 1269 1270 /* Code. */ 1271 1272 status = makeDateFromString( &user_date_format, time, string ); 1273 1274 1275 return( status ); 1276 1277 } /* TimMakeDateFromString */ 1278 1279 1280 /*----------------------------------------------------------------------*/ 1281 1282 TIM_STATUS_TYPE TimMakeDateFromIsoString(TIM_TIME_REF * time,char * string)1283 TimMakeDateFromIsoString( TIM_TIME_REF *time, 1284 char *string ) 1285 { 1286 1287 /* Variables. */ 1288 TIM_STATUS_TYPE status; 1289 1290 1291 /* Code. */ 1292 1293 status = makeDateFromString( &iso_date_format, time, string ); 1294 1295 1296 return( status ); 1297 1298 } /* TimMakeDateFromIsoString */ 1299 1300 1301 /*----------------------------------------------------------------------*/ 1302 1303 TIM_STATUS_TYPE TimMakeTimeFromString(TIM_TIME_REF * time,char * string)1304 TimMakeTimeFromString( TIM_TIME_REF *time, 1305 char *string ) 1306 { 1307 1308 /* Variables. */ 1309 TIM_STATUS_TYPE status; 1310 1311 1312 /* Code. */ 1313 1314 status = makeTimeFromString( &user_time_format, time, string ); 1315 1316 1317 return( status ); 1318 1319 } /* TimMakeTimeFromString */ 1320 1321 1322 /*----------------------------------------------------------------------*/ 1323 1324 TIM_STATUS_TYPE TimMakeTimeFromIsoString(TIM_TIME_REF * time,char * string)1325 TimMakeTimeFromIsoString( TIM_TIME_REF *time, 1326 char *string ) 1327 { 1328 1329 /* Variables. */ 1330 TIM_STATUS_TYPE status; 1331 1332 1333 /* Code. */ 1334 1335 status = makeTimeFromString( &iso_time_format, time, string ); 1336 1337 1338 return( status ); 1339 1340 } /* TimMakeTimeFromIsoString */ 1341 1342 1343 /*----------------------------------------------------------------------*/ 1344 1345 TIM_TIME_REF TimMakeTimeNow()1346 TimMakeTimeNow() 1347 { 1348 1349 /* Code. */ 1350 1351 return( (TIM_TIME_REF) time( NULL ) ); 1352 1353 } /* TimMakeTimeNow */ 1354 1355 1356 /*----------------------------------------------------------------------*/ 1357 1358 TIM_STATUS_TYPE TimMakeTimeFromWeek(int year,int week_number,TIM_TIME_REF * time)1359 TimMakeTimeFromWeek( int year, 1360 int week_number, 1361 TIM_TIME_REF *time ) 1362 { 1363 1364 /* Variables. */ 1365 TIM_TIME_REF new_time; 1366 1367 1368 /* Code. */ 1369 1370 new_time = TimMakeTime( year, 1, 1, 0, 0, 0 ); 1371 1372 TimAddDays( &new_time, (week_number - 2) * 7 ); 1373 1374 while( TimIndexOfWeek( new_time ) != week_number ) 1375 TimAddDays( &new_time, 1 ); 1376 1377 *time = new_time; 1378 1379 1380 return( TIM_OK ); 1381 1382 } /* TimMakeTimeFromWeek */ 1383 1384 1385 /*----------------------------------------------------------------------*/ 1386 1387 int TimMinute(TIM_TIME_REF time)1388 TimMinute( TIM_TIME_REF time ) 1389 { 1390 1391 /* Variables. */ 1392 struct tm *time_struct; 1393 struct tm time_struct_obj; 1394 1395 1396 /* Code. */ 1397 1398 time_struct = convertToStruct( time, &time_struct_obj ); 1399 1400 1401 return( time_struct -> tm_min ); 1402 1403 } /* TimMinute */ 1404 1405 1406 /*----------------------------------------------------------------------*/ 1407 1408 void TimNextDay(TIM_TIME_REF * time,TIM_DAY_TYPE time_of_day)1409 TimNextDay( TIM_TIME_REF *time, 1410 TIM_DAY_TYPE time_of_day ) 1411 { 1412 1413 /* Variables. */ 1414 struct tm *time_struct; 1415 struct tm time_struct_obj; 1416 1417 1418 /* Code. */ 1419 1420 TimAddDays( time, 1 ); 1421 1422 time_struct = convertToStruct( *time, &time_struct_obj ); 1423 1424 /* Set to a specific time of the day. */ 1425 switch( time_of_day ) { 1426 case TIM_NOON: 1427 time_struct -> tm_hour = 12; 1428 time_struct -> tm_min = 0; 1429 time_struct -> tm_sec = 0; 1430 1431 *time = (TIM_TIME_REF) secondsSince1970( time_struct ); 1432 break; 1433 1434 case TIM_MIDNIGHT: 1435 time_struct -> tm_hour = 0; 1436 time_struct -> tm_min = 0; 1437 time_struct -> tm_sec = 0; 1438 1439 *time = (TIM_TIME_REF) secondsSince1970( time_struct ); 1440 break; 1441 1442 default: 1443 break; 1444 1445 } /* switch */ 1446 1447 1448 return; 1449 1450 } /* TimNextDay */ 1451 1452 1453 /*----------------------------------------------------------------------*/ 1454 1455 void TimNextMonth(TIM_TIME_REF * time,TIM_MONTH_TYPE day_in_month)1456 TimNextMonth( TIM_TIME_REF *time, 1457 TIM_MONTH_TYPE day_in_month ) 1458 { 1459 1460 /* Variables. */ 1461 TIM_TIME_REF new_time; 1462 1463 1464 /* Code. */ 1465 1466 /* The end of this month. */ 1467 new_time = TimMakeTime( TimIndexOfYear( *time ), 1468 TimIndexOfMonth( *time ), 1469 TimDaysInMonth( *time ), 1470 0, 0, 0 ); 1471 1472 /* Add days so that we move to the next month. */ 1473 TimAddDays( &new_time, 1 ); 1474 1475 /* Which part of the month? */ 1476 switch( day_in_month ) { 1477 1478 case TIM_START_MONTH: 1479 break; 1480 1481 case TIM_END_MONTH: 1482 new_time = TimMakeTime( TimIndexOfYear( new_time ), 1483 TimIndexOfMonth( new_time ), 1484 TimDaysInMonth( new_time ), 1485 0, 0, 0 ); 1486 break; 1487 1488 } /* switch */ 1489 1490 *time = new_time; 1491 1492 1493 return; 1494 1495 } /* TimNextMonth */ 1496 1497 1498 /*----------------------------------------------------------------------*/ 1499 1500 void TimPreviousDay(TIM_TIME_REF * time,TIM_DAY_TYPE time_of_day)1501 TimPreviousDay( TIM_TIME_REF *time, 1502 TIM_DAY_TYPE time_of_day ) 1503 { 1504 1505 /* Variables. */ 1506 struct tm *time_struct; 1507 struct tm time_struct_obj; 1508 1509 1510 /* Code. */ 1511 1512 TimAddDays( time, -1 ); 1513 1514 time_struct = convertToStruct( *time, &time_struct_obj ); 1515 1516 /* Set to a specific time of the day. */ 1517 switch( time_of_day ) { 1518 case TIM_NOON: 1519 time_struct -> tm_hour = 12; 1520 time_struct -> tm_min = 0; 1521 time_struct -> tm_sec = 0; 1522 1523 *time = (TIM_TIME_REF) secondsSince1970( time_struct ); 1524 break; 1525 1526 case TIM_MIDNIGHT: 1527 time_struct -> tm_hour = 0; 1528 time_struct -> tm_min = 0; 1529 time_struct -> tm_sec = 0; 1530 1531 *time = (TIM_TIME_REF) secondsSince1970( time_struct ); 1532 break; 1533 1534 default: 1535 break; 1536 1537 } /* switch */ 1538 1539 1540 return; 1541 1542 } /* TimPreviousDay */ 1543 1544 1545 /*----------------------------------------------------------------------*/ 1546 1547 void TimPreviousMonth(TIM_TIME_REF * time,TIM_MONTH_TYPE day_in_month)1548 TimPreviousMonth( TIM_TIME_REF *time, 1549 TIM_MONTH_TYPE day_in_month ) 1550 { 1551 1552 /* Variables. */ 1553 TIM_TIME_REF new_time; 1554 1555 1556 /* Code. */ 1557 1558 /* The first in this month. */ 1559 new_time = TimMakeTime( TimIndexOfYear( *time ), 1560 TimIndexOfMonth( *time ), 1561 1, 0, 0, 0 ); 1562 1563 /* Add days so that we move to the end of next month. */ 1564 TimAddDays( &new_time, -1 ); 1565 1566 /* Which part of the month? */ 1567 switch( day_in_month ) { 1568 1569 case TIM_START_MONTH: 1570 new_time = TimMakeTime( TimIndexOfYear( new_time ), 1571 TimIndexOfMonth( new_time ), 1572 1, 0, 0, 0 ); 1573 break; 1574 1575 case TIM_END_MONTH: 1576 break; 1577 1578 } /* switch */ 1579 1580 *time = new_time; 1581 1582 1583 return; 1584 1585 } /* TimPreviousMonth */ 1586 1587 1588 /*----------------------------------------------------------------------*/ 1589 1590 int TimSecond(TIM_TIME_REF time)1591 TimSecond( TIM_TIME_REF time ) 1592 { 1593 1594 /* Variables. */ 1595 struct tm *time_struct; 1596 struct tm time_struct_obj; 1597 1598 1599 /* Code. */ 1600 1601 time_struct = convertToStruct( time, &time_struct_obj ); 1602 1603 1604 return( time_struct -> tm_sec ); 1605 1606 } /* TimSecond */ 1607 1608 1609 /*----------------------------------------------------------------------*/ 1610 1611 void TimSetUnixWeekNo(Boolean use_unix_week_no)1612 TimSetUnixWeekNo( Boolean use_unix_week_no ) 1613 { 1614 1615 /* Code. */ 1616 1617 unix_week_no = use_unix_week_no; 1618 1619 1620 return; 1621 1622 } /* TimSetUnixWeekNo */ 1623 1624 1625 /*----------------------------------------------------------------------*/ 1626 1627 TIM_STATUS_TYPE TimTimeInSecondsRange(TIM_TIME_REF master,TIM_TIME_REF check,int seconds_range)1628 TimTimeInSecondsRange( TIM_TIME_REF master, 1629 TIM_TIME_REF check, 1630 int seconds_range ) 1631 { 1632 1633 /* Code. */ 1634 if( abs( master - check ) <= (seconds_range / 2) ) 1635 return( TIM_YES ); 1636 1637 1638 return( TIM_NO ); 1639 1640 } /* TimTimeInSecondsRange */ 1641 1642 1643 /*----------------------------------------------------------------------*/ 1644 1645 char TimWhatDateFormat()1646 *TimWhatDateFormat() 1647 { 1648 1649 /* Code. */ 1650 1651 return( date_format_string ); 1652 1653 } /* TimWhatDateFormat */ 1654 1655 1656 /*----------------------------------------------------------------------*/ 1657 1658 char TimWhatTimeFormat()1659 *TimWhatTimeFormat() 1660 { 1661 1662 /* Code. */ 1663 1664 return( time_format_string ); 1665 1666 } /* TimWhatTimeFormat */ 1667 1668 1669 /*----------------------------------------------------------------------*/ 1670 1671 static struct tm convertToLocalStruct(TIM_TIME_REF time,struct tm * container)1672 *convertToLocalStruct( TIM_TIME_REF time, 1673 struct tm *container ) 1674 { 1675 1676 /* Variables. */ 1677 struct tm *ref; 1678 1679 1680 /* Code. */ 1681 1682 ref = localtime( (time_t *) &time ); 1683 1684 memcpy( container, ref, sizeof( struct tm ) ); 1685 1686 1687 return( container ); 1688 1689 } /* convertToLocalStruct */ 1690 1691 1692 /*----------------------------------------------------------------------*/ 1693 1694 static struct tm convertToStruct(TIM_TIME_REF time,struct tm * container)1695 *convertToStruct( TIM_TIME_REF time, 1696 struct tm *container ) 1697 { 1698 1699 /* Variables. */ 1700 struct tm *ref; 1701 1702 1703 /* Code. */ 1704 1705 ref = gmtime( (time_t *) &time ); 1706 1707 memcpy( container, ref, sizeof( struct tm ) ); 1708 1709 1710 return( container ); 1711 1712 } /* convertToStruct */ 1713 1714 1715 /*----------------------------------------------------------------------*/ 1716 1717 static int dayNumberInYear(int year,int month,int day)1718 dayNumberInYear( int year, 1719 int month, 1720 int day ) 1721 { 1722 1723 /* Code. */ 1724 1725 if( daysInYear( year ) == 366 ) 1726 return( day_offset_leap_year[ month - 1 ] + day ); 1727 1728 1729 return( day_offset[ month - 1 ] + day ); 1730 1731 } /* dayNumberInYear */ 1732 1733 1734 /*----------------------------------------------------------------------*/ 1735 1736 static int daysInYear(int year)1737 daysInYear( int year ) 1738 { 1739 1740 /* Code. */ 1741 1742 if( year % 4 == 0 ) 1743 return( 366 ); 1744 1745 1746 return( 365 ); 1747 1748 } /* daysInYear */ 1749 1750 1751 /*----------------------------------------------------------------------*/ 1752 1753 static void formatDate(DATE_FORMAT * date_format,TIM_TIME_REF time,char * buffer,int buffer_size)1754 formatDate( DATE_FORMAT *date_format, 1755 TIM_TIME_REF time, 1756 char *buffer, 1757 int buffer_size ) 1758 { 1759 1760 /* Variables. */ 1761 char day[ 10 ]; 1762 char month[ 10 ]; 1763 char year[ 10 ]; 1764 struct tm *time_struct; 1765 struct tm time_struct_obj; 1766 1767 1768 /* Code. */ 1769 1770 if( buffer_size < 11 ) { 1771 *buffer = '\0'; 1772 return; 1773 } 1774 1775 time_struct = convertToStruct( time, &time_struct_obj ); 1776 1777 /* Year. */ 1778 if( date_format -> include_century ) 1779 (void) strftime( year, sizeof( year ), "%Y", time_struct ); 1780 else 1781 (void) strftime( year, sizeof( year ), "%y", time_struct ); 1782 1783 /* Month. */ 1784 (void) strftime( month, sizeof( month ), "%m", time_struct ); 1785 if( ! date_format -> month_leading_zero && month[ 0 ] == '0' ) { 1786 month[ 0 ] = month[ 1 ]; 1787 month[ 1 ] = '\0'; 1788 } 1789 1790 /* Day. */ 1791 (void) strftime( day, sizeof( day ), "%d", time_struct ); 1792 if( ! date_format -> day_leading_zero && day[ 0 ] == '0' ) { 1793 day[ 0 ] = day[ 1 ]; 1794 day[ 1 ] = '\0'; 1795 } 1796 1797 /* Build the date. */ 1798 if( date_format -> order == DATE_MMDDYY ) 1799 sprintf( buffer, "%s%s%s%s%s", 1800 month, date_format -> separator, 1801 day, date_format -> separator, 1802 year ); 1803 else if( date_format -> order == DATE_DDMMYY ) 1804 sprintf( buffer, "%s%s%s%s%s", 1805 day, date_format -> separator, 1806 month, date_format -> separator, 1807 year ); 1808 else 1809 sprintf( buffer, "%s%s%s%s%s", 1810 year, date_format -> separator, 1811 month, date_format -> separator, 1812 day ); 1813 1814 1815 return; 1816 1817 } /* formatDate */ 1818 1819 1820 /*----------------------------------------------------------------------*/ 1821 1822 static void formatFullDate(DATE_FORMAT * date_format,TIM_TIME_REF time,char * buffer,int buffer_size)1823 formatFullDate( DATE_FORMAT *date_format, 1824 TIM_TIME_REF time, 1825 char *buffer, 1826 int buffer_size ) 1827 { 1828 1829 /* Variables. */ 1830 char day[ 10 ]; 1831 char month[ 10 ]; 1832 char year[ 10 ]; 1833 struct tm *time_struct; 1834 struct tm time_struct_obj; 1835 1836 1837 /* Code. */ 1838 1839 if( buffer_size < 30 ) { 1840 *buffer = '\0'; 1841 return; 1842 } 1843 1844 time_struct = convertToStruct( time, &time_struct_obj ); 1845 1846 /* Year. */ 1847 (void) strftime( year, sizeof( year ), "%Y", time_struct ); 1848 1849 /* Month. */ 1850 (void) strftime( month, sizeof( month ), "%B", time_struct ); 1851 1852 /* Day. */ 1853 (void) strftime( day, sizeof( day ), "%d", time_struct ); 1854 if( day[ 0 ] == '0' ) { 1855 day[ 0 ] = day[ 1 ]; 1856 day[ 1 ] = '\0'; 1857 } 1858 1859 /* Build the date. */ 1860 if( date_format -> order == DATE_MMDDYY ) 1861 sprintf( buffer, "%s %s, %s", month, day, year ); 1862 else if( date_format -> order == DATE_DDMMYY ) 1863 sprintf( buffer, "%s. %s %s", day, month, year ); 1864 else 1865 sprintf( buffer, "%s. %s %s", day, month, year ); 1866 1867 1868 return; 1869 1870 } /* formatFullDate */ 1871 1872 1873 /*----------------------------------------------------------------------*/ 1874 1875 static void formatTime(TIME_FORMAT * time_format,TIM_TIME_REF time,char * buffer,int buffer_size)1876 formatTime( TIME_FORMAT *time_format, 1877 TIM_TIME_REF time, 1878 char *buffer, 1879 int buffer_size ) 1880 { 1881 1882 /* Variables. */ 1883 char hour[ 10 ]; 1884 char minute[ 10 ]; 1885 struct tm *time_struct; 1886 struct tm time_struct_obj; 1887 1888 1889 /* Code. */ 1890 1891 if( buffer_size < 9 ) { 1892 *buffer = '\0'; 1893 return; 1894 } 1895 1896 time_struct = convertToStruct( time, &time_struct_obj ); 1897 1898 /* Hour. */ 1899 if( time_format -> hour_12 ) 1900 (void) strftime( hour, sizeof( hour ), "%I", time_struct ); 1901 else 1902 (void) strftime( hour, sizeof( hour ), "%H", time_struct ); 1903 1904 if( ! time_format -> hour_leading_zero && hour[ 0 ] == '0' ) { 1905 hour[ 0 ] = hour[ 1 ]; 1906 hour[ 1 ] = '\0'; 1907 } 1908 1909 /* Minute. */ 1910 (void) strftime( minute, sizeof( minute ), "%M", time_struct ); 1911 1912 /* Build the time. */ 1913 if( TimHour( time ) > 11 ) 1914 sprintf( buffer, "%s%s%s%s%s", 1915 hour, time_format -> separator, 1916 minute, time_format -> hour_24_suffix_separator, 1917 time_format -> hour_24_suffix ); 1918 else 1919 sprintf( buffer, "%s%s%s%s%s", 1920 hour, time_format -> separator, 1921 minute, time_format -> hour_12_suffix_separator, 1922 time_format -> hour_12_suffix ); 1923 1924 1925 return; 1926 1927 } /* formatTime */ 1928 1929 1930 /*----------------------------------------------------------------------*/ 1931 1932 static TIM_STATUS_TYPE isTimeOk(int year,int month,int day,int hour,int minute,int second)1933 isTimeOk( int year, 1934 int month, 1935 int day, 1936 int hour, 1937 int minute, 1938 int second ) 1939 { 1940 1941 /* Variables. */ 1942 TIM_TIME_REF time; 1943 1944 1945 /* Code. */ 1946 1947 /* The easy check. */ 1948 #ifdef NO_RXTN 1949 if( year < 1900 ) 1950 year = year + 1900; 1951 #else 1952 if ( year < 1970 ) { 1953 if ( year >= 70 && year < 100 ) 1954 year += 1900; 1955 else 1956 if ( year <= 30 ) 1957 year += 2000; 1958 else 1959 return TIM_ERROR; 1960 } 1961 else 1962 if ( year > 2030 ) 1963 return TIM_ERROR; 1964 #endif 1965 1966 if( year < 1970 || year > 2100 || 1967 month < 1 || month > 12 || 1968 day < 1 || day > 31 || 1969 hour < 0 || hour > 23 || 1970 minute < 0 || minute > 59 || 1971 second < 0 || second > 59 ) 1972 return( TIM_ERROR ); 1973 1974 time = TimMakeTime( year, month, 1, 0, 0, 0 ); 1975 1976 if( day > TimDaysInMonth( time ) ) 1977 return( TIM_ERROR ); 1978 1979 1980 return( TIM_OK ); 1981 1982 } /* isTimeOk */ 1983 1984 1985 /*----------------------------------------------------------------------*/ 1986 1987 static TIM_STATUS_TYPE makeDateFromString(DATE_FORMAT * date_format,TIM_TIME_REF * time,char * string)1988 makeDateFromString( DATE_FORMAT *date_format, 1989 TIM_TIME_REF *time, 1990 char *string ) 1991 { 1992 1993 /* Variables. */ 1994 Boolean has_match = False; 1995 int day = 1; 1996 int matches; 1997 int month = 1; 1998 int par1; 1999 int par2; 2000 int par3; 2001 int year = 1970; 2002 2003 struct tm *time_struct; 2004 struct tm time_struct_obj; 2005 2006 2007 /* Code. */ 2008 2009 *time = TimLocalTime( TimMakeTimeNow() ); 2010 2011 time_struct = convertToStruct( *time, &time_struct_obj ); 2012 2013 time_struct -> tm_hour = 0; 2014 time_struct -> tm_min = 0; 2015 time_struct -> tm_sec = 0; 2016 2017 2018 /* Three parameters? */ 2019 if( ! has_match ) { 2020 matches = sscanf( string, date_format -> ymd_format, 2021 &par1, &par2, &par3 ); 2022 if( matches == 3 ) 2023 has_match = True; 2024 } 2025 2026 /* Two parameters? */ 2027 if( ! has_match ) { 2028 matches = sscanf( string, date_format -> md_format, 2029 &par1, &par2 ); 2030 if( matches == 2 ) 2031 has_match = True; 2032 } 2033 2034 /* One parameters? */ 2035 if( ! has_match ) { 2036 matches = sscanf( string, date_format -> d_format, 2037 &par1 ); 2038 if( matches == 1 ) 2039 has_match = True; 2040 } 2041 2042 /* Any matches? */ 2043 if( ! has_match ) 2044 return( TIM_ERROR ); 2045 2046 /* MMDDYY format. */ 2047 if( date_format -> order == DATE_MMDDYY ) { 2048 if( matches == 3 ) { 2049 year = par3; 2050 month = par1; 2051 day = par2; 2052 } else if( matches == 2 ) { 2053 year = time_struct -> tm_year; 2054 month = par1; 2055 day = par2; 2056 } else { 2057 year = time_struct -> tm_year; 2058 month = time_struct -> tm_mon + 1; 2059 day = par1; 2060 } 2061 } 2062 2063 /* DDMMYY format. */ 2064 if( date_format -> order == DATE_DDMMYY ) { 2065 if( matches == 3 ) { 2066 year = par3; 2067 month = par2; 2068 day = par1; 2069 } else if( matches == 2 ) { 2070 year = time_struct -> tm_year; 2071 month = par2; 2072 day = par1; 2073 } else { 2074 year = time_struct -> tm_year; 2075 month = time_struct -> tm_mon + 1; 2076 day = par1; 2077 } 2078 } 2079 2080 /* YYMMDD format. */ 2081 if( date_format -> order == DATE_YYMMDD ) { 2082 if( matches == 3 ) { 2083 year = par1; 2084 month = par2; 2085 day = par3; 2086 } else if( matches == 2 ) { 2087 year = time_struct -> tm_year; 2088 month = par1; 2089 day = par2; 2090 } else { 2091 year = time_struct -> tm_year; 2092 month = time_struct -> tm_mon + 1; 2093 day = par1; 2094 } 2095 } 2096 2097 2098 /* Check the time. */ 2099 if( isTimeOk( year, month, day, 0, 0, 0 ) != TIM_OK ) 2100 return( TIM_ERROR ); 2101 2102 /* Build the time. */ 2103 if( year < 1000 ) 2104 time_struct -> tm_year = year; 2105 else 2106 time_struct -> tm_year = year - 1900; 2107 2108 time_struct -> tm_mon = month - 1; 2109 time_struct -> tm_mday = day; 2110 time_struct -> tm_yday = dayNumberInYear( year, month, day ) - 1; 2111 2112 time_struct -> tm_hour = 0; 2113 time_struct -> tm_min = 0; 2114 time_struct -> tm_sec = 0; 2115 2116 *time = secondsSince1970( time_struct ); 2117 2118 2119 return( TIM_OK ); 2120 2121 } /* makeDateFromString */ 2122 2123 2124 /*----------------------------------------------------------------------*/ 2125 2126 static TIM_STATUS_TYPE makeTimeFromString(TIME_FORMAT * time_format,TIM_TIME_REF * time,char * string)2127 makeTimeFromString( TIME_FORMAT *time_format, 2128 TIM_TIME_REF *time, 2129 char *string ) 2130 { 2131 2132 /* Variables. */ 2133 Boolean before_12 = False; 2134 Boolean has_match = False; 2135 int hour; 2136 int matches; 2137 int minute; 2138 int par1; 2139 int par2; 2140 char suffix[ 50 ]; 2141 2142 struct tm *time_struct; 2143 struct tm time_struct_obj; 2144 2145 2146 /* Code. */ 2147 2148 *time = TimLocalTime( TimMakeTimeNow() ); 2149 2150 time_struct = convertToStruct( *time, &time_struct_obj ); 2151 2152 hour = time_struct -> tm_hour; 2153 minute = time_struct -> tm_min; 2154 2155 2156 /* Two parameters? */ 2157 if( ! has_match ) { 2158 if( time_format -> hour_12 ) { 2159 matches = sscanf( string, time_format -> hm_format, 2160 &par1, &par2, suffix ); 2161 if( matches == 3 ) 2162 has_match = True; 2163 } else { 2164 matches = sscanf( string, time_format -> hm_format, 2165 &par1, &par2 ); 2166 if( matches == 2 ) 2167 has_match = True; 2168 } 2169 } 2170 2171 /* One parameter? */ 2172 if( ! has_match ) { 2173 if( time_format -> hour_12 ) { 2174 matches = sscanf( string, time_format -> hm_format, 2175 &par1, suffix ); 2176 if( matches == 2 ) 2177 has_match = True; 2178 } else { 2179 matches = sscanf( string, time_format -> hm_format, 2180 &par1 ); 2181 if( matches == 1 ) 2182 has_match = True; 2183 } 2184 } 2185 2186 /* Any matches? */ 2187 if( ! has_match ) 2188 return( TIM_ERROR ); 2189 2190 /* 12-hour suffix? */ 2191 if( time_format -> hour_12 && matches == 3 ) { 2192 if( noCaseStrcmp( suffix, time_format -> hour_12_suffix ) == 0 ) 2193 before_12 = True; 2194 else if( noCaseStrcmp( suffix, time_format -> hour_24_suffix ) == 0 ) 2195 before_12 = False; 2196 else 2197 return( TIM_ERROR ); 2198 } 2199 2200 2201 /* Build the time. */ 2202 if( time_format -> hour_12 ) { 2203 if( matches == 3 ) { 2204 hour = par1; 2205 minute = par2; 2206 2207 /* 12 AM = 0:00, 12 PM = 12:00. */ 2208 if( ! before_12 && hour != 12 ) 2209 hour = hour + 12; 2210 else if( before_12 && hour == 12 ) 2211 hour = 0; 2212 2213 } else { 2214 minute = par1; 2215 } 2216 } 2217 2218 if( ! time_format -> hour_12 ) { 2219 if( matches == 2 ) { 2220 hour = par1; 2221 minute = par2; 2222 } else { 2223 minute = par1; 2224 } 2225 } 2226 2227 2228 /* Check the time. */ 2229 if( isTimeOk( 1970, 1, 1, hour, minute, 0 ) != TIM_OK ) 2230 return( TIM_ERROR ); 2231 2232 time_struct -> tm_year = 70; 2233 time_struct -> tm_mon = 0; 2234 time_struct -> tm_mday = 1; 2235 time_struct -> tm_yday = 0; 2236 2237 time_struct -> tm_hour = hour; 2238 time_struct -> tm_min = minute; 2239 time_struct -> tm_sec = 0; 2240 2241 *time = secondsSince1970( time_struct ); 2242 2243 2244 return( TIM_OK ); 2245 2246 } /* makeTimeFromString */ 2247 2248 2249 /*----------------------------------------------------------------------*/ 2250 2251 static int noCaseStrcmp(char * buffer1,char * buffer2)2252 noCaseStrcmp( char *buffer1, 2253 char *buffer2 ) 2254 { 2255 2256 /* Variables. */ 2257 char *char_ref1; 2258 char *char_ref2; 2259 2260 2261 /* Code. */ 2262 2263 if( strlen( buffer1 ) != strlen( buffer2 ) ) 2264 return( strcmp( buffer1, buffer2 ) ); 2265 2266 char_ref1 = buffer1; 2267 char_ref2 = buffer2; 2268 2269 while( *char_ref1 != '\0' ) { 2270 if( tolower( *char_ref1 ) < tolower( *char_ref2 ) ) 2271 return( -1 ); 2272 else if( tolower( *char_ref1 ) > tolower( *char_ref2 ) ) 2273 return( 1 ); 2274 2275 char_ref1++; 2276 char_ref2++; 2277 } 2278 2279 2280 return( 0 ); 2281 2282 } /* noCaseStrcmp */ 2283 2284 2285 /*----------------------------------------------------------------------*/ 2286 2287 static time_t secondsSince1970(struct tm * time_ref)2288 secondsSince1970( struct tm *time_ref ) 2289 { 2290 2291 /* Variables. */ 2292 int index; 2293 time_t seconds = 0; 2294 2295 2296 /* Code. */ 2297 2298 if( time_ref -> tm_year < 70 ) 2299 return( 0 ); 2300 2301 for( index = 70 + 1900; index < time_ref -> tm_year + 1900; index++ ) 2302 seconds = seconds + (daysInYear( index ) * 86400); 2303 2304 seconds = seconds + time_ref -> tm_yday * 86400; 2305 seconds = seconds + time_ref -> tm_hour * 3600; 2306 seconds = seconds + time_ref -> tm_min * 60; 2307 seconds = seconds + time_ref -> tm_sec; 2308 2309 2310 return( seconds ); 2311 2312 } /* secondsSince1970 */ 2313