Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | tighter coding of the date and time functions. Better comments. A bug fix. (CVS 1070) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
94243edac14b90ef898093b85e1959c2 |
User & Date: | drh 2003-08-10 01:50:55.000 |
Context
2003-08-10
| ||
16:16 | Make the sqliteOsCurrentTime() function work for Windows. Code contributed by "e4liberty" on the mailing list. (CVS 1071) (check-in: 02fac304c9 user: drh tags: trunk) | |
01:50 | tighter coding of the date and time functions. Better comments. A bug fix. (CVS 1070) (check-in: 94243edac1 user: drh tags: trunk) | |
2003-08-09
| ||
21:32 | Add experimental date and time functions based on julian day number. (CVS 1069) (check-in: a6197e2075 user: drh tags: trunk) | |
Changes
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.28 2003/08/10 01:50:55 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "os.h" |
︙ | ︙ | |||
499 500 501 502 503 504 505 | } /**************************************************************************** ** Time and date functions. ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon | | > > | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | } /**************************************************************************** ** Time and date functions. ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ** ** This implement requires years to be expressed as a 4-digit number ** which means that only dates between 0000-01-01 and 9999-12-31 can ** be represented, even though julian day numbers allow a much wider ** range of dates. ** ** The Gregorian calendar system is used for all dates and times, ** even those that predate the Gregorian calendar. Historians usually ** use the Julian calendar for dates prior to 1582-10-15 and for some ** dates afterwards, depending on locale. Beware of this difference. ** ** The conversion algorithms are implemented based on descriptions ** in the following text: ** ** Jean Meeus |
︙ | ︙ | |||
536 537 538 539 540 541 542 | val = val*10 + *zDate - '0'; zDate++; } return val; } /* | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | val = val*10 + *zDate - '0'; zDate++; } return val; } /* ** Parse times of the form HH:MM:SS or HH:MM. Store the ** result (in days) in *prJD. ** ** Return 1 if there is a parsing error and 0 on success. */ static int parseHhMmSs(const char *zDate, double *prJD){ int h, m, s; h = getDigits(zDate, 2); |
︙ | ︙ | |||
641 642 643 644 645 646 647 | *prJD = atof(zDate); return 0; } return 1; } /* | > > > > > > > > > > | > > > > | | | > > | | | | | | | | | | > > | > > > > | | > | | > | > > > > > | | < < < < < | | > > | | | | | < < < < < < | | | < < < < < < | | | < < | | | < < | | | < < | | | | | | < < | | | < < < < < < | | | < < < < < | | | < < < | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 | *prJD = atof(zDate); return 0; } return 1; } /* ** A structure for holding date and time. */ typedef struct DateTime DateTime; struct DateTime { double rJD; /* The julian day number */ int Y, M, D; /* Year, month, and day */ int h, m, s; /* Hour minute and second */ }; /* ** Break up a julian day number into year, month, day, hour, minute, second. ** This function assume the Gregorian calendar - even for dates prior ** to the invention of the Gregorian calendar in 1582. ** ** See Meeus page 63. ** ** If mode==1 only the year, month, and day are computed. If mode==2 ** then only the hour, minute, and second are computed. If mode==3 then ** everything is computed. If mode==0, this routine is a no-op. */ static void decomposeDate(DateTime *p, int mode){ int Z; Z = p->rJD + 0.5; if( mode & 1 ){ int A, B, C, D, E, X1; A = (Z - 1867216.25)/36524.25; A = Z + 1 + A - (A/4); B = A + 1524; C = (B - 122.1)/365.25; D = 365.25*C; E = (B-D)/30.6001; X1 = 30.6001*E; p->D = B - D - X1; p->M = E<14 ? E-1 : E-13; p->Y = p->M>2 ? C - 4716 : C - 4715; } if( mode & 2 ){ p->s = (p->rJD + 0.5 - Z)*86400.0; p->h = p->s/3600; p->s -= p->h*3600; p->m = p->s/60; p->s -= p->m*60; } } /* ** Check to see that all arguments are valid date strings. If any ** argument is not a valid date string, return 0. If all arguments ** are valid, return 1 and write into *p->rJD the sum of the julian day ** numbers for all date strings. ** ** A "valid" date string is one that is accepted by parseDateOrTime(). ** ** The mode argument is passed through to decomposeDate() in order to ** fill in the year, month, day, hour, minute, and second of the *p ** structure, if desired. */ static int isDate(int argc, const char **argv, DateTime *p, int mode){ double r; int i; p->rJD = 0.0; for(i=0; i<argc; i++){ if( argv[i]==0 ) return 0; if( parseDateOrTime(argv[i], &r) ) return 0; p->rJD += r; } decomposeDate(p, mode); return 1; } /* ** The following routines implement the various date and time functions ** of SQLite. */ static void juliandayFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 0) ){ sqlite_set_result_double(context, x.rJD); } } static void timestampFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 3) ){ char zBuf[100]; sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m, x.s); sqlite_set_result_string(context, zBuf, -1); } } static void timeFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 2) ){ char zBuf[100]; sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, x.s); sqlite_set_result_string(context, zBuf, -1); } } static void dateFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 1) ){ char zBuf[100]; sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D); sqlite_set_result_string(context, zBuf, -1); } } static void yearFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 1) ){ sqlite_set_result_int(context, x.Y); } } static void monthFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 1) ){ sqlite_set_result_int(context, x.M); } } static void dayofweekFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 0) ){ int Z = x.rJD + 1.5; sqlite_set_result_int(context, Z % 7); } } static void dayofmonthFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 1) ){ sqlite_set_result_int(context, x.D); } } static void secondFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 2) ){ sqlite_set_result_int(context, x.s); } } static void minuteFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 2) ){ sqlite_set_result_int(context, x.m); } } static void hourFunc(sqlite_func *context, int argc, const char **argv){ DateTime x; if( isDate(argc, argv, &x, 2) ){ sqlite_set_result_int(context, x.h); } } #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ /***************************************************************************/ /* ** This function registered all of the above C functions as SQL |
︙ | ︙ |