📄 sfldate.c
字号:
/* ----------------------------------------------------------------<Prolog>-
Name: sfldate.c
Title: Date and time functions
Package: Standard Function Library (SFL)
Written: 1996/01/06 iMatix SFL project team <sfl@imatix.com>
Revised: 2000/01/19
Copyright: Copyright (c) 1996-2000 iMatix Corporation
License: This is free software; you can redistribute it and/or modify
it under the terms of the SFL License Agreement as provided
in the file LICENSE.TXT. This software is distributed in
the hope that it will be useful, but without any warranty.
------------------------------------------------------------------</Prolog>-*/
#include "prelude.h" /* Universal header file */
#include "sflprint.h" /* snprintf functions */
#include "sfldate.h" /* Prototypes for functions */
/* ---------------------------------------------------------------------[<]-
Function: date_now
Synopsis: Returns the current date as a long value (CCYYMMDD). Since
most system clocks do not return a century, this function assumes that
all years 80 and above are in the 20th century, and all years 00 to 79
are in the 21st century. For best results, consume before 1 Jan 2080.
---------------------------------------------------------------------[>]-*/
long
date_now (void)
{
return (timer_to_date (time (NULL)));
}
/* ---------------------------------------------------------------------[<]-
Function: time_now
Synopsis: Returns the current time as a long value (HHMMSSCC). If the
system clock does not return centiseconds, these are set to zero.
---------------------------------------------------------------------[>]-*/
long
time_now (void)
{
#if (defined (__TURBOC__))
/* The Turbo-C gettime() function returns just what we want */
struct time
time_struct;
gettime (&time_struct);
return (MAKE_TIME (time_struct.ti_hour,
time_struct.ti_min,
time_struct.ti_sec,
time_struct.ti_hund));
#elif (defined (__UTYPE_FREEBSD__))
return (timer_to_time (time (NULL)));
#elif (defined (__UNIX__) || defined (__VMS_XOPEN))
/* The BSD gettimeofday function returns seconds and microseconds */
struct timeval
time_struct;
gettimeofday (&time_struct, 0);
return (timer_to_time (time_struct.tv_sec)
+ time_struct.tv_usec / 10000);
#elif (defined (WIN32))
/* The Win32 GetLocalTime function returns just what we want */
SYSTEMTIME
time_struct;
GetLocalTime (&time_struct);
return (MAKE_TIME (time_struct.wHour,
time_struct.wMinute,
time_struct.wSecond,
time_struct.wMilliseconds / 10));
#else
/* Otherwise, just get the time without milliseconds */
return (timer_to_time (time (NULL)));
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: leap_year
Synopsis: Returns TRUE if the year is a leap year. You must supply a
4-digit value for the year: 90 is taken to mean 90 ad. Handles leap
centuries correctly.
---------------------------------------------------------------------[>]-*/
Bool
leap_year (int year)
{
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
/* ---------------------------------------------------------------------[<]-
Function: julian_date
Synopsis: Returns the number of days since 31 December last year. The
Julian date of 1 January is 1.
---------------------------------------------------------------------[>]-*/
int
julian_date (long date)
{
static int
days [12] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
int
julian;
julian = days [GET_MONTH (date) - 1] + GET_DAY (date);
if (GET_MONTH (date) > 2 && leap_year (GET_YEAR (date)))
julian++;
return (julian);
}
/* ---------------------------------------------------------------------[<]-
Function: day_of_week
Synopsis: Returns the day of the week where 0 is Sunday, 1 is Monday,
... 6 is Saturday. Uses Zeller's Congurence algorithm.
---------------------------------------------------------------------[>]-*/
int
day_of_week (long date)
{
int
year = GET_CCYEAR (date),
month = GET_MONTH (date),
day = GET_DAY (date);
if (month > 2)
month -= 2;
else
{
month += 10;
year--;
}
day = ((13 * month - 1) / 5) + day + (year % 100) +
((year % 100) / 4) + ((year / 100) / 4) - 2 *
(year / 100) + 77;
return (day - 7 * (day / 7));
}
/* ---------------------------------------------------------------------[<]-
Function: next_weekday
Synopsis: Returns the date of the next weekday, skipping from Friday
to Monday.
---------------------------------------------------------------------[>]-*/
long
next_weekday (long date)
{
long
days = date_to_days (date);
if (day_of_week (date) == 5) /* Friday */
days += 3;
else
if (day_of_week (date) == 6) /* Saturday */
days += 2;
else
days += 1; /* Sunday to Thursday */
return (days_to_date (days));
}
/* ---------------------------------------------------------------------[<]-
Function: prev_weekday
Synopsis: Returns the date of the previous weekday, skipping from Monday
to Friday.
---------------------------------------------------------------------[>]-*/
long
prev_weekday (long date)
{
long
days = date_to_days (date);
if (day_of_week (date) == 1) /* Monday */
days -= 3;
else
if (day_of_week (date) == 0) /* Sunday */
days -= 2;
else
days -= 1; /* Tuesday to Saturday */
return (days_to_date (days));
}
/* ---------------------------------------------------------------------[<]-
Function: week_of_year
Synopsis: Returns the week of the year, where 1 is the first full week.
Week 0 may or may not exist in any year. Uses a Lillian date algorithm
to calculate the week of the year.
---------------------------------------------------------------------[>]-*/
int
week_of_year (long date)
{
long
year = GET_CCYEAR (date) - 1501,
day = year * 365 + year / 4 - 29872L + 1
- year / 100 + (year - 300) / 400;
return ((julian_date (date) + (int) ((day + 4) % 7)) / 7);
}
/* ---------------------------------------------------------------------[<]-
Function: year_quarter
Synopsis: Returns the year quarter, 1 to 4, depending on the month
specified.
---------------------------------------------------------------------[>]-*/
int
year_quarter (long date)
{
return ((GET_MONTH (date) - 1) / 3 + 1);
}
/* ---------------------------------------------------------------------[<]-
Function: default_century
Synopsis: Supplies a default century for the year if necessary. If
the year is 51 to 99, the century is set to 19. If the year is 0 to
50, the century is set to 20. Returns the adjusted date.
---------------------------------------------------------------------[>]-*/
long
default_century (long *date)
{
if (GET_CENTURY (*date) == 0)
*date += (GET_YEAR (*date) > 50? 19000000L: 20000000L);
return (*date);
}
/* ---------------------------------------------------------------------[<]-
Function: pack_date
Synopsis: Packs the date into a single unsigned short word. Use this
function to store dates when memory space is at a premium. The packed
date can be used correctly in comparisons. Returns the packed date.
The date must be later than 31 December 1979.
---------------------------------------------------------------------[>]-*/
word
pack_date (long date)
{
return (word) (((GET_CCYEAR (date) - 1980) << 9) +
(GET_MONTH (date) << 5) +
GET_DAY (date));
}
/* ---------------------------------------------------------------------[<]-
Function: pack_time
Synopsis: Packs the time into a single unsigned short word. Use this
function to store times when memory space is at a premium. The packed
time can be used correctly in comparisons. Returns the packed time.
Seconds are stored with 2-second accuracy and centiseconds are lost.
---------------------------------------------------------------------[>]-*/
word
pack_time (long time)
{
return (word) ((GET_HOUR (time) << 11) +
(GET_MINUTE (time) << 5) +
(GET_SECOND (time) >> 1));
}
/* ---------------------------------------------------------------------[<]-
Function: unpack_date
Synopsis: Converts a packed date back into a long value.
---------------------------------------------------------------------[>]-*/
long
unpack_date (word packdate)
{
int year;
year = ((word) (packdate & 0xfe00) >> 9) + 80;
return (MAKE_DATE (year > 80? 19: 20,
year,
(word) (packdate & 0x01e0) >> 5,
(word) (packdate & 0x001f)));
}
/* ---------------------------------------------------------------------[<]-
Function: unpack_time
Synopsis: Converts a packed time back into a long value.
---------------------------------------------------------------------[>]-*/
long
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -