comparison src/editfns.c @ 2921:37503f466755

Some time-handling patches from Paul Eggert: * editfns.c (Fcurrent_time_zone): Take an optional argument specifying what (absolute) time should be used to determine the current time zone. Yield just offset and name of time zone, including DST correction. Yield time zone offset in seconds, not minutes. (lisp_time_argument, difftm): New functions. (Fcurrent_time_string): Use lisp_time_argument. * systime.h (EMACS_CURRENT_TIME_ZONE, EMACS_GET_TZ_OFFSET, EMACS_GET_TZ_NAMES): Remove. * config.h.in: Add HAVE_TM_ZONE.
author Jim Blandy <jimb@redhat.com>
date Thu, 20 May 1993 06:29:45 +0000
parents 789c11177579
children 79314d830f7d
comparison
equal deleted inserted replaced
2920:c47652dc3400 2921:37503f466755
539 539
540 return Flist (3, result); 540 return Flist (3, result);
541 } 541 }
542 542
543 543
544 static int
545 lisp_time_argument (specified_time, result)
546 Lisp_Object specified_time;
547 time_t *result;
548 {
549 if (NILP (specified_time))
550 return time (result) != -1;
551 else
552 {
553 Lisp_Object high, low;
554 high = Fcar (specified_time);
555 CHECK_NUMBER (high, 0);
556 low = Fcdr (specified_time);
557 if (XTYPE (low) == Lisp_Cons)
558 low = Fcar (low);
559 CHECK_NUMBER (low, 0);
560 *result = (XINT (high) << 16) + (XINT (low) & 0xffff);
561 return *result >> 16 == XINT (high);
562 }
563 }
564
544 DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0, 565 DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
545 "Return the current time, as a human-readable string.\n\ 566 "Return the current time, as a human-readable string.\n\
546 Programs can use this function to decode a time,\n\ 567 Programs can use this function to decode a time,\n\
547 since the number of columns in each field is fixed.\n\ 568 since the number of columns in each field is fixed.\n\
548 The format is `Sun Sep 16 01:03:52 1973'.\n\ 569 The format is `Sun Sep 16 01:03:52 1973'.\n\
554 Thus, you can use times obtained from `current-time'\n\ 575 Thus, you can use times obtained from `current-time'\n\
555 and from `file-attributes'.") 576 and from `file-attributes'.")
556 (specified_time) 577 (specified_time)
557 Lisp_Object specified_time; 578 Lisp_Object specified_time;
558 { 579 {
559 long value; 580 time_t value;
560 char buf[30]; 581 char buf[30];
561 register char *tem; 582 register char *tem;
562 583
563 if (NILP (specified_time)) 584 if (! lisp_time_argument (specified_time, &value))
564 value = time ((long *) 0); 585 value = -1;
565 else
566 {
567 Lisp_Object high, low;
568 high = Fcar (specified_time);
569 CHECK_NUMBER (high, 0);
570 low = Fcdr (specified_time);
571 if (XTYPE (low) == Lisp_Cons)
572 low = Fcar (low);
573 CHECK_NUMBER (low, 0);
574 value = ((XINT (high) << 16) + (XINT (low) & 0xffff));
575 }
576
577 tem = (char *) ctime (&value); 586 tem = (char *) ctime (&value);
578 587
579 strncpy (buf, tem, 24); 588 strncpy (buf, tem, 24);
580 buf[24] = 0; 589 buf[24] = 0;
581 590
582 return build_string (buf); 591 return build_string (buf);
583 } 592 }
584 593
585 DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 0, 0, 594 #define TM_YEAR_ORIGIN 1900
586 "Return the offset, savings state, and names for the current time zone.\n\ 595
587 This returns a list of the form (OFFSET SAVINGS-FLAG STANDARD SAVINGS).\n\ 596 /* Yield A - B, measured in seconds. */
588 OFFSET is an integer specifying how many minutes east of Greenwich the\n\ 597 static long
589 current time zone is located. A negative value means west of\n\ 598 difftm(a, b)
590 Greenwich. Note that this describes the standard time; if daylight\n\ 599 struct tm *a, *b;
591 savings time is in effect, it does not affect this value.\n\ 600 {
592 SAVINGS-FLAG is non-nil iff daylight savings time or some other sort\n\ 601 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
593 of seasonal time adjustment is in effect.\n\ 602 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
594 STANDARD is a string giving the name of the time zone when no seasonal\n\ 603 return
595 time adjustment is in effect.\n\ 604 (
596 SAVINGS is a string giving the name of the time zone when there is a\n\ 605 (
597 seasonal time adjustment in effect.\n\ 606 (
598 If the local area does not use a seasonal time adjustment,\n\ 607 /* difference in day of year */
599 SAVINGS-FLAG is always nil, and STANDARD and SAVINGS are equal.\n\ 608 a->tm_yday - b->tm_yday
609 /* + intervening leap days */
610 + ((ay >> 2) - (by >> 2))
611 - (ay/100 - by/100)
612 + ((ay/100 >> 2) - (by/100 >> 2))
613 /* + difference in years * 365 */
614 + (long)(ay-by) * 365
615 )*24 + (a->tm_hour - b->tm_hour)
616 )*60 + (a->tm_min - b->tm_min)
617 )*60 + (a->tm_sec - b->tm_sec);
618 }
619
620 DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0,
621 "Return the offset and name for the local time zone.\n\
622 This returns a list of the form (OFFSET NAME).\n\
623 OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).\n\
624 A negative value means west of Greenwich.\n\
625 NAME is a string giving the name of the time zone.\n\
626 If an argument is given, it specifies when the time zone offset is determined\n\
627 instead of using the current time. The argument should have the form:\n\
628 (HIGH . LOW)\n\
629 or the form:\n\
630 (HIGH LOW . IGNORED).\n\
631 Thus, you can use times obtained from `current-time'\n\
632 and from `file-attributes'.\n\
600 \n\ 633 \n\
601 Some operating systems cannot provide all this information to Emacs;\n\ 634 Some operating systems cannot provide all this information to Emacs;\n\
602 in this case, current-time-zone will return a list containing nil for\n\ 635 in this case, current-time-zone will return a list containing nil for\n\
603 the data it can't find.") 636 the data it can't find.")
604 () 637 (specified_time)
605 { 638 Lisp_Object specified_time;
606 #ifdef EMACS_CURRENT_TIME_ZONE 639 {
607 int offset, savings_flag; 640 time_t value;
608 char standard[11]; 641 struct tm *t;
609 char savings[11]; 642
610 643 if (lisp_time_argument (specified_time, &value)
611 EMACS_CURRENT_TIME_ZONE (&offset, &savings_flag, standard, savings); 644 && (t = gmtime(&value)) != 0)
612 645 {
613 return Fcons (make_number (offset), 646 struct tm gmt = *t; /* Make a copy, in case localtime modifies *t. */
614 Fcons ((savings_flag ? Qt : Qnil), 647 long offset;
615 Fcons (build_string (standard), 648 char *s, buf[6];
616 Fcons (build_string (savings), 649 t = localtime(&value);
617 Qnil)))); 650 offset = difftm(t, &gmt);
618 #else 651 s = 0;
619 return Fmake_list (4, Qnil); 652 #ifdef HAVE_TM_ZONE
653 if (t->tm_zone)
654 s = t->tm_zone;
620 #endif 655 #endif
656 if (!s)
657 {
658 /* No local time zone name is available; use "+-NNNN" instead. */
659 long am = (offset < 0 ? -offset : offset) / 60;
660 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
661 s = buf;
662 }
663 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
664 }
665 else
666 return Fmake_list (2, Qnil);
621 } 667 }
622 668
623 669
624 void 670 void
625 insert1 (arg) 671 insert1 (arg)