THIS SECTION IS UNDER CONSTRUCTION
Есть различные способы измерения времени. В настоящее время на нашей планете используются разные системы исчисления времени, но все они сходятся на том что у нас есть день, в котором есть часы, минуты секунды. Но с месяцами и годами все уже обстоит по другому. Григорианский календарь (от рождества Христова) Лунная Хиджра (арабский календарь) Восточные календари (масса вариантов). и еще куча других Как правило в компьютерном мире мы сталкиваемся с Григорианский календарем.
1 день = 24 часа = 1440 минут = 86400 секунд 1 час = 60 минут = 3600 секунд 1 минута = 60 секунд 1 сек = 10^9 наносек 1 сек = 1000000 микросек 1 сек = 1000 миллисек Месяц. Количество дней в месяце зависит от его номера. Для февраля возможен дополнительный день в високосные года. Thirty days have September, April, June and November, And one day more, One year in four. Месяц кол-во дней January 31 February 28/29 March 31 April 30 May 31 June 30 July 31 August 31 September 30 October 31 November 30 December 31 Таким образов в году получается 365/366 дней Не каждый год является високосным: Не кратный 4 - простой кратный 4 - високосный Исключение - xx00 - если последние две цифры номера года нули - простой Исключение - xx00 - если последние две цифры номера года нули, и если часть номера года предшествующая двум последним цифрам делиться на 4 без остатка, то - високосный 2007 - простой 2006 - простой 2005 - простой 2004 - високосный 1896 - високосный 1900 - простой 1904 - високосный .... 1996 - високосный 2000 - високосный 2004 - високосный .... 2096 - високосный 2100 - простой 2104 - високосный 0 года не было был 1 год д.н.э 1 год н.э Поэтому начало нового тысячелетия было - 1 января 2001 года, а не 1 января 2000 года Коррекции календаря: Юлианский Грегорианский Юлианский календарь - христианская церковь 325 г н.э. Грегорианский был введен Oct 15, 1582 (это был Oct 5,1582 в Юлианском). Принимался Грегорианский календарь медленно: Великобритания 1752 Россия 1918 Греция 1923 Разница в том, что xx00 - всегда считались високосными в Юлианском календаре Сейчас разница уже - 13 дней (эта разница действует: с 1 марта 1900 до 29 фев 2100) Коперник родился 19 февраля 1473 года (естественно Юлианский календарь) для XV века разница 9 дней соответсвенно 19 + 9 = 28 февраля 1473 года по новому стилю. Календарь от Рождества Христова
День недели Считаем по разному В России первый день недели - понедельник В Англоязычных странах - Sunday Форматы разные: 12.01.07 // RUS: DD.MM.YY 01/12/07 // US: MM/DD/YY 12/01/07 // UK: DD/MM/YY DD.MM.YYYY Russia YYYY.MM.DD Japan MM/DD/YYYY US DD/MM/YYYY UK и на время: 12:23:00 // RUS: HH:MM:SS.msec 23:10 12:03am // US: HH:MMLL 12-часовой, 24-часовой AM 0:00-11:59 PM 12:00-23:59 HTTP Cookies: Fri, 03 Dec 2010 ISO 8601 2010-12-03 T06:23:39-0500 RFC822 Fri, 03 Dec 2010 06:23:39 EST RFC850 Friday, 03-Dec-10 06:23:39 EST Номер недели в году Неделя A) ISO 8601:1988 та которая 4 дня общее правило - неделя на которой 4 или более дней принадлежит новому году - является его неделей номер 1 B) начинается с Sunday C) начинается с Monday начинается с 1 (1-53) # День недели сокращенно 0 Sunday Sun воскресение 1 Monday Mon понедельник 2 Tuesday Tue вторник 3 Wednesday Wed среда 4 Thursday Thu четверг 5 Friday Fri пятница 6 Saturday Sat суббота Days per month January 31 Январь February 28/29 Февраль March 31 Март April 30 Апрель May 31 Май June 30 Июнь July 31 Июль August 31 Август September 30 Сентябрь October 31 Октябрь November 30 Ноябрь December 31 Декабрь Advanced: Корректирующие секунды: 00:00:00 23:59:59 23:59:60 коректирующая секунда 23:59:61 тоже корректирующая секунда В любом случае из-за приливов вращение земли замедляется. Форматы представления
Time Zone Поясное время В Москве 15:00, в Петрапавловске-на-Камчатке полночь. Time Zone
GMT Greenwich Mean Time EST Eastern Standart Time (GMT-5) US CST Central Standart Time (GMT-6) US MST Mountain Standart Time (GMT-7) US PST Pasific Standart Time (GMT-8) US HST Hawaiian Standart Time (GMT-10) US EST Eastern Standart Time (GMT+10) Австралия CST Central Standart Time (GMT+9:30) Австралия CET Centroeuropean time (GMT+1) вся западная европа кроме Португалии EET East European time (GMT+2) London GMT Moscow GMT+03 Los Angeles GMT-07 UTC = GMT без DST +-HHMM Секунды -12 -43200 -11 -39600 -10 -36000 -9 -32400 -8 -28800 -7 -25200 -6 -21600 -5 -18000 -4 -14400 -3.5 -12600 -3 -10800 0 0 1 3600 2 7200 3 10800 3.5 12600 4 14400 4.5 16200 5 18000 5.5 19800 5.75 20700 6 21600 6.5 23400 7 25200 8 28800 9 32400 9.5 34200 10 36000 12 43200 Линия перемены дат У нас в России есть 2 места - где сходяться сразу 3 timezone. Так решали вопрос - где покупать водку когда поздно. (Хотя населенных пунктов там нет). Летнее и зимнее время В целях экономии электроэнергии. Daylight Saving Time В разных странах переход на летнее время осуществляется в разное время Например MSK-LA разница в зависимости от даты может быть 11 или 12 часов. Переход на летнее время В 2 часа ночи - становиться 3 часа ночи Перевод на зимнее время: В 3 часа ночи - снова становиться 2 час ночи Россия: последнее воскресение марта (на 1 час вперед) последнее воскресение октября (на 1 час назад) США в 2005 принят новый закон о летнем времени вступил в силу с 2007 до 2007 - первое воскресение апреля c 2007 - на 3 недели раньше до 2007 - последнее воскресение октября с 2007 - первое воскресение ноября. Проблема наследования неделимого майората и близнецов Первый родился - 1:49 (до перевода времени) Второй рождился - 1:20 (после перевода времени) в один и тот же день когда переводили время Старшинство по нотариально заверенным показаниям акушерки. Время / \ UTC Локальное Как правило современные компьютеры имеют при инсталляции checkbox, который показывает что время в CMOS RTC настроено как локальное или как UTC. Для UTC нет зимнего и летнего времени (в отличии от GMT). NTFS хранит время в UTC. FAT хранит время - Local time. Современные OS имеют функцию автокорекции времени в CMOS RTC при переходе на/c летнее время (если RTC время стоит локальным). В случае нескольких OS на компьютере в результате их запуска происходит множественная коррекция времени. Конечно лучше всего иметь время в RTC как UTC.
Основные форматы времени Связанны с OS и с дисковыми структурами и сетевыми пакетами DOS DOSDATE { unsigned DayOfMonth:5; // 1..31 unsigned MonthOfYear:4; // 1..12 unsigned Year:7; // 0..127 - means 1980..2107 } DOSTIME { unsigned SecondsDiv2:5; // 0..29 means 0..58 seconds unsigned Minutes:6; // 0..59 unsigned Hour:5; // 0..23 } Windows NT 64-битный тип показывающий время в 100ns интервалах начиная с 1 января 1601 года (UTC) typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, UNIX struct timespec { time_t tv_sec; // количество секунд начиная с 00:00:00 1 Jan 1970 GMT long tv_nsec; } CDFS cdfs_time_date { char NumberOfYearSince1900; // 0..255 cover 1900..2255 char MonthOfYear; // 1..12 char DayOfMonth; // 1..31 char HourOfDay; // 0..23 char MinuteOfHour; // 0..59 char SecondOfMinute; // 0..59 char OffsetFromGreewich; // contain practically Timezone } UDF udf_timestamp { word TypeAndTimezone; word Year; // 0..65535 byte Month; // 1..12 byte Day; // 1..31 byte Hour; // 0..23 byte Minute; // 0..59 byte Second; // 0..59 byte CentiSeconds; // 0..99 byte HundredsOfms; // 0..99 byte Millisec; // 0..99 } Бывают и приватные форматы: например Microsoft VirtualPC VHD диски считают свой timestamp в секундах начиная с 00:00:00 1-Jan-2000. Основные форматы времени
Проблема 2000 года Y2K problem: Представление года в виде одного байта числом 91 - 1991 год 98 - 1998 год 00 - 2000 год, но в числовой форме - 00 < 91 - получаются ошибки. На самом деле самое страшное что нас ждет - это конец UNIX эпохи. Y2038 19 Jan 2038 3:14:07 UTC = 2147483647 sec on epoch 1-Jan-1970
Для работы требуется два вида времени Время / \ Календарное Интервальное Операционные системы для внутренних целей пользуются как правило интервальным временем с момента последней загрузки. Это основное время для внутренних синхронизаций - помому что календарное время может быть изменено (например изменена time zone, или летнее/зимнее). Так же есть определенные проблемы связанные с middleware - синхронизация времени между различными компьютерами. При небольших расхождениях бывают просто несколько убыстряют или замедляют отчет. Убыстряют - начинают обработчик вызывать чаще чем 1 раз в тик замедляют - не каждый тик
Времена: Реальное Время выполнения процесса/нити Как правило с этим временем связаны процессорные квоты для процесса/ниты. Монотонное системное время Как правило отсчитывается от момента запуска системы Синхронизационные события завязаны именно на него Оно никогда не уменьшается Коррекции времени как правило убыстряют или замедляют скорость изменения монотонного системного времени на некоторое время. Для разных задач требуются разные типы времен.
Источники времени: RTC (Real Time Clock) встоен во все компьютеры питается от батарейки, разрешающая способность - обычно не более 1/10 секунды. точность невысокая - бывают случае когда за год время уползает минут на 20 (особенно если батарейка совсем плохая). 2007 12 31 24:00:00 12 31/30/29/28 24 60 60 Проблемы: Имеет время обновления в процессе которого данные не consistance Timer - тоже есть во всех компьютерах - переодически дает прерывания, кроме того его можно прочитать. Прерывания обычно идут с частотой от 18.2 Hz, до 1000 Hz в зависимости от платформы и настроек. Обычно используется как основной источник для интервального времени операционной системы. В отличии от RTC как правило читается атомарно TSC (Time Stamp Counter) - в современных процессорах есть специальные регистры которые прибавляют к себе 1 каждый такт синхронизации. К сожалению это не панацея, потому что например при перегреве процессора он может понижать внутреннюю тактовую частоту - что отражается на скорости обновления счетчика.
Специальный случай - Watchdog Timer. Он работает следующим образом. После того как к нему было обращение он начинает отсчитывать интервал времени, как интервал закончен он выдает сигнал, который как правило завязан на сигнал RESET и осуществляет сброс машины. Это повышает надежность - если система зависла (т.е. не обращается определенное время к Watchdog timer), то ее сбрасывают аппаратно и она перезагружается.
Источники календарного времени: RTC Синхронизируем время с сервером по сети. Источники: Точные атомные часы Коллективные дисциплины: Коллективные дисциплины: 0 0 0 0 0 0 +2 -11 -3 +5 +8 +3 обрабытавают статистику, выбрасывают сильные отклонения. затем рассчитываем коррекцию
Какие вообще требования у программ к временным задержкам: 1) Schedule Надо что бы функция/программа вызвалась 1-Jan-2007 в 21:43:04 Как правило это делает специализированная программа - например croт демон Либо (если функция) то операционная система Точность как правило не очень важна. 1/10 секунды погоды не делает. 2) Interval Надо что бы функция вызвалась чераз 3.5 секунды Это делает операционная система, которой говорят Эта нить ждет объект таймера (а в объекте таймера уже стоит 3.5 cек вперед) 3) Micro Delay Мы работаем с оборудованием, и нам надо выждать маленькое количество времени (например 100ns, при этом если мы получим управление позже чем 200ns нам это тоже не поможет - поэтому нам не надо, что бы нас вытесняли. То есть работа происходит в той же нити.
По хорошему абсолютное время это пара Локальное время UTC время TimeZone 0 к которой хороше бы добавить (Daylight Saving) Yes/No чтобы избежать множественных коррекций Получить системное время Установить системное время (доп привелегии) Получить Timezone Установить Timezone (доп привелегии) Перевести абсолютное время в другую timezone из UTC в Local Time из Local Time в UTC (возможны варианты: в указанную time zone). Сравнить абсолютные времена (кто больше) Получить интервальное время из 2х абсолютных Форматный ввод/вывод времени т.е. преобразование даты/времени в строку и обратно Ждать указанное число времени (Вообще говоря деляться на 2 категории tick-based и speen-wait). Delay MicroDelay Получать сообщения с интервалом столько то времени Запустить Пауза/Продолжить Отменить Может быть разная семантика: например пока не вышел - новое сообщение не запускаем или запускаем или внутри всегда надо снова запускать. или автоматический перезапуск. Концептуальный RTL для работы со временем
UNIX ------------------------------------------------------------ sec usec nsec time_t timeval timespec ------------------------------------------------------------ Get time time gettimeofday clock_gettime Set time stime settimeofday clock_settime Sleep sleep select nanosleep Get ------------------------------------------------------------ Реальные интерфейсы
//time.h typedef long time_t; struct timespec { time_t tv_sec; long tv_nsec; }; struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; // if daylight saving #ifdef _BSD_SOURCE long tm_gmtoff; const char* tm_zone; #endif }; time_t time(time_t* t); int stime(time_t* t); clock_t clock() // process time int clock_gettime(clockid_t clock_id, struct timespec* ts); int clock_settime(clockid_t clock_id, struct timespec ts); clockid_t: CLOCK_MONOTONIC CLOCK_PROCESS_CPUTIME_ID CLOCK_REALTIME CLOCK_THREAD_CPUTIME_ID char* asctime(const struct tm* tm); char* asctime_r(const struct tm* tm, char* buf); time_t mktime(struct tm* tm); char* ctime(const time_t* timep); char* ctime_r(const time_t* timep, char* buf); struct tm * gmtime(const time_t* timep); // to UTC struct tm * gmtime_r(const time_t* timep, struct tm* result); struct tm * localtime(const time_t* timep); // to local struct tm * localtime_r(const time_t* timep, struct tm * result); double difftime(time_t time1, time_t time0); // in seconds "Tue Jun 17 23:17:28 1997\n\0" struct tm* getdate(const char* s); Non-standard: time_t timegm(struct tm* tp); int nanosleep(const struct timespec* req, const struct timespec* rem); int clock_nanosleep(clockid_t clock_id, // POSIX int flags, const struct timespec* req, struct timespec* rem); size_t strftime(char*s, size_t max, char* fmt, struct tm* tp); // printf analog %a 3-char name of weekday %A full name of weekday %b 3-char name of month %B full name of month %c preffered local expression of time or date (ctime()/asctime()) %d day of month (count from 0) %H hour of day 24 hour mode %I hour of day 12 hour mode %j day of year (1..) %m month (1..) %M minute (0..) %p AM or PM %S seconds (0..) %U week of year [week 1 start first Sunday of year] %W week of year [week 1 start first Monday of year] %w day of week %x local date expression %X local time expression %y last 2 digits of year %Y full 4digit year %Z standart abrv for time zone %% % char* strptime(char*s, char* fmt, struct tm* tp); // scanf analog Wide: wcsftime(wchar_t* buf, size_t bufsize, const wchar_t* format, const struct tm* tmbuf); wcsptime struct timeval tv = { .tv_sec = 0, .tv_usec = 757 }; select(0, NULL, NULL, NULL); extern int daylight; extern long timezone; extern day *tzname[2]; // [0] = standart time // [1] = dst void tzset(void); // заполняет переменные. // TZ enviroment variable //set TZ=EST5EDT // Eastern standart time // 5 delta // EDT - in daylight time QNX time.h void nsec2timespec(struct timespec* timespec_p, _uint64 nsec); _uint64 timespec2nsec(struct timespec* timespec_p); |
//sys/time.h struct timeval { time_t tv_sec; suseconds_t tv_usec; }; struct timezone { int tz_minuteswest; int tz_dsttime; // DST correction }; int gettimeofday(struct timeval* tv, struct timezone* tz); int settimeofday(const struct timeval* tv, const struct timezone* tz); int adjtime(const struct timeval* delta, const struct timeval* olddelta); macroses: timerclear(struct timeval) timerisset(struct timeval) timercmp(struct timeval t0, struct timeval t1); |
//sys/times.h struct tms { clock_t tms_utime; // user time clock_t tms_stime; // childs user time clock_t tms_cutime; // kernel time clock_t tms_cstime; // childs kernel time }; |
//sys/timex.h int adjtimex(struct timex* adj); struct timex!!! |
//unistd.h unsigned int sleep(unsigned int seconds); //BSD void usleep(unsigned long usec); //SUS int usleep(useconds_t usec); |
SYSTEMTIME VOID GetSystemTime(LPSYSTEMTIME lpst) SetSystemTime GetLocalTime BOOL SetLocalTime DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION*) SetTimeZoneInformation typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, * LPSYSTEMTIME; typedef struct _TIME_ZONE_INFORMATION { LONG Bias; TCHAR StandardName[32]; SYSTEMTIME StandardDate; LONG StandardBias; TCHAR DaylightName[32]; SYSTEMTIME DaylightDate; LONG DaylightBias; } TIME_ZONE_INFORMATION, * LPTIME_ZONE_INFORMATION; |