void to_tm(unsigned long tim, struct rtc_time * tm) { long hms, day, gday; int i; gday = day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ tm->tm_hour = hms / 3600; tm->tm_min = (hms % 3600) / 60; tm->tm_sec = (hms % 3600) % 60; /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) day -= days_in_year(i); tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) day -= days_in_month(i); days_in_month(FEBRUARY) = 28; tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; /* * Determine the day of week */ tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ }
/* * .func tm_to_secs - convert to seconds. * .desc Convert a tm time structure (time.h) into seconds since * Jan 1, 1970 00:00:00. The time is assumed to be GMT and * so no daylight savings time correction is applied. That * is left up to the system calls (localtime(), gmtime()). * .call ret = tm_to_secs(tme). * .arg tme - ptr to tm structure. * .ret time_t - number of seconds. */ time_t tm_to_secs(struct tm *tme) { int leap_year = FALSE; int days = 0; time_t num_sec = 0; int sec = tme->tm_sec; int min = tme->tm_min; int hour = tme->tm_hour; int day = tme->tm_mday; int month = tme->tm_mon; int year = tme->tm_year + 1900; if (days_in_year(year) == 366) leap_year = TRUE; while (year > 1970) { num_sec += days_in_year(--year) * 24 * 60 * 60; } while (month > 0) { days = days_month[--month]; if (leap_year && month == 1) { /* 1 is February */ days++; } num_sec += days * 24 * 60 * 60; } num_sec += --day * 24 * 60 * 60; num_sec += hour * 60 * 60; num_sec += min * 60; num_sec += sec; return (num_sec); }
void to_tm(int tim, MV_RTC_TIME *tm) { register int i; register long hms, day, gday; gday = day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ tm->hours = hms / 3600; tm->minutes = (hms % 3600) / 60; tm->seconds = (hms % 3600) % 60; /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) day -= days_in_year(i); tm->year = i; /* Number of months in days left */ if (leapyear(tm->year)) days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) day -= days_in_month(i); days_in_month(FEBRUARY) = 28; tm->month = i; /* Days are what is left over (+1) from all that. */ tm->date = day + 1; /* * Determine the day of week. Jan. 1, 1970 was a Thursday. */ tm->day = (gday + 4) % 7; }
long date::timestamp() const { static const int days_before_month[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; // Compute days in a year long days = (m_day - 1) + (days_before_month[m_month.index() - 1]); // Leap year adjustment if (m_month > month::jan && days_in_year() == 366) { ++days; } // Compute days in other years if (m_year > 1970) { for (int y = 1970; y < m_year; ++y) { days += days_in_year(y); } } else if (m_year < 1970) { for (int y = 1969; y >= m_year; --y) { days -= days_in_year(y); } } return days * 86400; }
void clock_ts_to_ct(struct timespec *ts, struct clocktime *ct) { time_t i, year, days; time_t rsec; /* remainder seconds */ time_t secs; secs = ts->tv_sec; days = secs / SECDAY; rsec = secs % SECDAY; ct->dow = day_of_week(days); /* Subtract out whole years, counting them in i. */ for (year = POSIX_BASE_YEAR; days >= days_in_year(year); year++) days -= days_in_year(year); ct->year = year; /* Subtract out whole months, counting them in i. */ for (i = 1; days >= days_in_month(year, i); i++) days -= days_in_month(year, i); ct->mon = i; /* Days are what is left over (+1) from all that. */ ct->day = days + 1; /* Hours, minutes, seconds are easy */ ct->hour = rsec / 3600; rsec = rsec % 3600; ct->min = rsec / 60; rsec = rsec % 60; ct->sec = rsec; ct->nsec = ts->tv_nsec; if (ct_debug) { printf("ts_to_ct(%ld.%09ld) = ", (long)ts->tv_sec, (long)ts->tv_nsec); print_ct(ct); printf("\n"); } KASSERT(ct->year >= 0 && ct->year < 10000, ("year %d isn't a 4 digit year", ct->year)); KASSERT(ct->mon >= 1 && ct->mon <= 12, ("month %d not in 1-12", ct->mon)); KASSERT(ct->day >= 1 && ct->day <= 31, ("day %d not in 1-31", ct->day)); KASSERT(ct->hour >= 0 && ct->hour <= 23, ("hour %d not in 0-23", ct->hour)); KASSERT(ct->min >= 0 && ct->min <= 59, ("minute %d not in 0-59", ct->min)); /* Not sure if this interface needs to handle leapseconds or not. */ KASSERT(ct->sec >= 0 && ct->sec <= 60, ("seconds %d not in 0-60", ct->sec)); }
main() { // loop over all days in 1988 and 1989 // (doesn't raise Time::date_objection) for( int i=1; i<=days_in_year(1988)+days_in_year(1989); i++ ) { Time t = Time::julian(1988,i); // ... } cout << endl; return 0; }
time_t clock_ymdhms_to_secs(struct clock_ymdhms *dt) { time_t secs; int i, year, days; year = dt->dt_year; /* * Compute days since start of time. * First from years, then from months. */ days = 0; for (i = POSIX_BASE_YEAR; i < year; i++) days += days_in_year(i); if (leapyear(year) && dt->dt_mon > FEBRUARY) days++; /* Months */ for (i = 1; i < dt->dt_mon; i++) days += days_in_month(i); days += (dt->dt_day - 1); /* Add hours, minutes, seconds. */ secs = (time_t)((days * 24 + dt->dt_hour) * 60 + dt->dt_min) * 60 + dt->dt_sec; return (secs); }
static int is_sunday(int day, int month, int year) { int days = day-1; for(int y = 1900; y < year; ++y) days += days_in_year(y); for(int m = 1; m < month; ++m) days += days_in_month(m, year); return (days % 7) == 6; }
int rtc_to_tm(int tim, struct rtc_time *tm) { register int i; register long hms, day; day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ tm->tm_hour = hms / 3600; tm->tm_min = (hms % 3600) / 60; tm->tm_sec = (hms % 3600) % 60; /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) { day -= days_in_year(i); } tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) { days_in_month(FEBRUARY) = 29; } for (i = 1; day >= days_in_month(i); i++) { day -= days_in_month(i); } days_in_month(FEBRUARY) = 28; tm->tm_mon = i; /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; /* Zero unused fields */ tm->tm_yday = 0; tm->tm_isdst = 0; /* * Determine the day of week */ return rtc_calc_weekday(tm); }
void clock_ts_to_ct(struct timespec *ts, struct clocktime *ct) { int i, year, days; time_t rsec; /* remainder seconds */ time_t secs; secs = ts->tv_sec; days = secs / SECDAY; rsec = secs % SECDAY; ct->dow = day_of_week(days); /* Subtract out whole years, counting them in i. */ for (year = POSIX_BASE_YEAR; days >= days_in_year(year); year++) days -= days_in_year(year); ct->year = year; /* Subtract out whole months, counting them in i. */ for (i = 1; days >= days_in_month(year, i); i++) days -= days_in_month(year, i); ct->mon = i; /* Days are what is left over (+1) from all that. */ ct->day = days + 1; /* Hours, minutes, seconds are easy */ ct->hour = rsec / 3600; rsec = rsec % 3600; ct->min = rsec / 60; rsec = rsec % 60; ct->sec = rsec; ct->nsec = ts->tv_nsec; if (ct_debug) { printf("ts_to_ct(%ld.%09ld) = ", (long)ts->tv_sec, (long)ts->tv_nsec); print_ct(ct); printf("\n"); } }
static int log_play_time( struct deltadb *db, time_t starttime, time_t stoptime ) { int file_errors = 0; struct tm *starttm = localtime(&starttime); int year = starttm->tm_year + 1900; int day = starttm->tm_yday; struct tm *stoptm = localtime(&stoptime); int stopyear = stoptm->tm_year + 1900; int stopday = stoptm->tm_yday; char *filename = string_format("%s/%d/%d.ckpt",db->logdir,year,day); checkpoint_read(db,filename); free(filename); while(1) { char *filename = string_format("%s/%d/%d.log",db->logdir,year,day); FILE *file = fopen(filename,"r"); if(!file) { file_errors += 1; fprintf(stderr,"couldn't open %s: %s\n",filename,strerror(errno)); free(filename); if (file_errors>5) break; } else { free(filename); int keepgoing = deltadb_process_stream(db,file,starttime,stoptime); starttime = 0; fclose(file); // If we reached the endtime in the file, stop. if(!keepgoing) break; } day++; if(day>=days_in_year(year)) { year++; day = 0; } // If we have passed the file, stop. if(year>=stopyear && day>stopday) break; } return 1; }
void to_tm(u32 tim, struct rtc_time * tm) { register u32 i; register long hms, day; day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ tm->tm_hour = hms / 3600; tm->tm_min = (hms % 3600) / 60; tm->tm_sec = (hms % 3600) % 60; /* Number of years in days */ /*算出当前年份,起始的计数年份为1970年*/ for (i = STARTOFTIME; day >= days_in_year(i); i++) { day -= days_in_year(i); } tm->tm_year = i; /* Number of months in days left */ /*计算当前的月份*/ if (leapyear(tm->tm_year)) { days_in_month(FEBRUARY) = 29; } for (i = 1; day >= days_in_month(i); i++) { day -= days_in_month(i); } days_in_month(FEBRUARY) = 28; tm->tm_mon = i; /* Days are what is left over (+1) from all that. *//*计算当前日期*/ tm->tm_mday = day + 1; /* * Determine the day of week */ GregorianDay(tm); }
void clock_secs_to_ymdhms(time_t secs, struct clock_ymdhms *dt) { int mthdays[12]; int i, days; int rsec; /* remainder seconds */ memcpy(mthdays, month_days, sizeof(mthdays)); days = secs / SECDAY; rsec = secs % SECDAY; /* Day of week (Note: 1/1/1970 was a Thursday) */ dt->dt_wday = (days + 4) % 7; /* Subtract out whole years, counting them in i. */ for (i = POSIX_BASE_YEAR; days >= days_in_year(i); i++) days -= days_in_year(i); dt->dt_year = i; /* Subtract out whole months, counting them in i. */ if (leapyear(i)) days_in_month(FEBRUARY) = 29; for (i = 1; days >= days_in_month(i); i++) days -= days_in_month(i); dt->dt_mon = i; /* Days are what is left over (+1) from all that. */ dt->dt_day = days + 1; /* Hours, minutes, seconds are easy */ dt->dt_hour = rsec / 3600; rsec = rsec % 3600; dt->dt_min = rsec / 60; rsec = rsec % 60; dt->dt_sec = rsec; }
/* * .func check_time - check tm structure. * .desc Check the time in a tm structure to see if all of the fields * are within range. * .call err = check_time(tme). * .arg tme - ptr to struct tm (see time.h). * .ret 0 - time is ok. * .ret -1 - time had a problem (description in error_str). */ int check_time(struct tm *tme) { error_str = NULL; if (tme->tm_sec < 0 || tme->tm_sec > 59) { (void) sprintf(errbuf, gettext("seconds out of range (%d)"), tme->tm_sec + 1); error_str = errbuf; } else if (tme->tm_min < 0 || tme->tm_min > 59) { (void) sprintf(errbuf, gettext("minutes out of range (%d)"), tme->tm_min + 1); error_str = errbuf; } else if (tme->tm_hour < 0 || tme->tm_hour > 23) { (void) sprintf(errbuf, gettext("hours out of range (%d)"), tme->tm_hour + 1); error_str = errbuf; } else if (tme->tm_mon < 0 || tme->tm_mon > 11) { (void) sprintf(errbuf, gettext("months out of range (%d)"), tme->tm_mon + 1); error_str = errbuf; } else if (tme->tm_year < 0) { (void) sprintf(errbuf, gettext("years out of range (%d)"), tme->tm_year); error_str = errbuf; } else if (tme->tm_mday < 1 || tme->tm_mday > days_month[tme->tm_mon]) { if (!(days_in_year(tme->tm_year + 1900) == 366 && tme->tm_mon == 1 && tme->tm_mday == 29)) { /* leap year and February */ (void) sprintf(errbuf, gettext("days out of range (%d)"), tme->tm_mday); error_str = errbuf; } } else if (tme->tm_wday < 0 || tme->tm_wday > 6) { (void) sprintf(errbuf, gettext("weekday out of range (%d)"), tme->tm_wday); error_str = errbuf; } else if (tme->tm_yday < 0 || tme->tm_yday > 365) { (void) sprintf(errbuf, gettext("day of year out of range (%d)"), tme->tm_yday); error_str = errbuf; } if (error_str == NULL) return (0); else return (-1); }
bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon, unsigned year ) { assert( (int)yday < days_in_year( year ) ); unsigned const *const ym = yday_mon[ is_leap_year( year ) ]; for ( unsigned m = 1; m <= 12; ++m ) if ( ym[ m ] > yday ) { --m; if ( mday ) *mday = yday - ym[ m ] + 1; if ( mon ) *mon = m; return true; } return false; }
int clock_ct_to_ts(struct clocktime *ct, struct timespec *ts) { time_t secs; int i, year, days; year = ct->year; if (ct_debug) { printf("ct_to_ts("); print_ct(ct); printf(")"); } /* Sanity checks. */ if (ct->mon < 1 || ct->mon > 12 || ct->day < 1 || ct->day > days_in_month(year, ct->mon) || ct->hour > 23 || ct->min > 59 || ct->sec > 59 || ct->year > 2037) { /* time_t overflow */ if (ct_debug) printf(" = EINVAL\n"); return (EINVAL); } /* * Compute days since start of time * First from years, then from months. */ days = 0; for (i = POSIX_BASE_YEAR; i < year; i++) days += days_in_year(i); /* Months */ for (i = 1; i < ct->mon; i++) days += days_in_month(year, i); days += (ct->day - 1); /* Add hours, minutes, seconds. */ secs = ((days * 24 + ct->hour) * 60 + ct->min) * 60 + ct->sec; ts->tv_sec = secs; ts->tv_nsec = ct->nsec; if (ct_debug) printf(" = %ld.%09ld\n", (long)ts->tv_sec, (long)ts->tv_nsec); return (0); }
int bbc_to_gmt(u_long *timbuf) { int i; u_long tmp; int year, month, day, hour, min, sec; read_bbc(); sec = bbc_to_decimal(1, 0); min = bbc_to_decimal(3, 2); /* * Hours are different for some reason. Makes no sense really. */ hour = ((bbc_registers[5] & 0x03) * 10) + bbc_registers[4]; day = bbc_to_decimal(8, 7); month = bbc_to_decimal(10, 9); year = bbc_to_decimal(12, 11) + 1900; range_test(hour, 0, 23); range_test(day, 1, 31); range_test(month, 1, 12); range_test(year, STARTOFTIME, 2038); /* 2038 is the end of time. */ tmp = 0; for (i = STARTOFTIME; i < year; i++) tmp += days_in_year(i); if (leapyear(year) && month > FEBRUARY) tmp++; for (i = 1; i < month; i++) tmp += days_in_month(i); tmp += (day - 1); tmp = ((tmp * 24 + hour) * 60 + min) * 60 + sec; *timbuf = tmp; return(1); }
/* Convert a struct tm into seconds since 1970-01-01T00:00 * Ignores timezones, daylight savings, and leap seconds. */ uint32_t maketime(struct tm *time) { uint32_t t = 0; uint16_t i; /* Seconds, minutes, hours: easy */ t += time->tm_sec; t += time->tm_min * 60; t += time->tm_hour * 60 * 60; /* Tot up time in months before this one */ /* Remember struct tm years are since 1900 */ for(i=0; i<time->tm_mon; i++) t += days_in_month(i, 1900+time->tm_year) * 24 * 60 * 60; /* Tot up all the time in years before this one */ /* Remember struct tm years are since 1900 */ for(i=1970; i<time->tm_year; i++) t += days_in_year(1900+i) * 24 * 60 * 60; return t; }
bool Hebrew::is_long_marheshvan (double h_year) { double d = days_in_year (h_year); return (d == 355.0f || d == 385.0f); }
bool Hebrew::is_short_kislev (double h_year) { double d = days_in_year (h_year); return (d == 353.0f || d == 383.0f); }
/* * Display a dialog box for entering a date */ int dialog_calendar(const char *title, const char *subtitle, int height, int width, int day, int month, int year) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_ENTER, ' ' ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, DLGK_MOUSE(KEY_NPAGE) ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_GRID_LEFT, '-' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, CHR_BACKSPACE ), DLG_KEYS_DATA( DLGK_GRID_LEFT, CHR_PREVIOUS ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, '+' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, CHR_NEXT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_NEXT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_GRID_UP, 'k' ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_PREVIOUS ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), DLG_KEYS_DATA( DLGK_GRID_UP, DLGK_MOUSE(KEY_PPAGE) ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif BOX dy_box, mn_box, yr_box; int fkey; int key = 0; int key2; int step; int button; int result = DLG_EXIT_UNKNOWN; WINDOW *dialog; time_t now_time = time((time_t *) 0); struct tm current; int state = dlg_default_button(); const char **buttons = dlg_ok_labels(); char *prompt = dlg_strclone(subtitle); int mincols = MIN_WIDE; char buffer[MAX_LEN]; DIALOG_VARS save_vars; dlg_save_vars(&save_vars); dialog_vars.separate_output = TRUE; dlg_does_output(); now_time = time((time_t *) 0); current = *localtime(&now_time); if (day < 0) day = current.tm_mday; if (month < 0) month = current.tm_mon + 1; if (year < 0) year = current.tm_year + 1900; /* compute a struct tm that matches the day/month/year parameters */ if (((year -= 1900) > 0) && (year < 200)) { /* ugly, but I'd like to run this on older machines w/o mktime -TD */ for (;;) { if (year > current.tm_year) { now_time += ONE_DAY * days_in_year(¤t, 0); } else if (year < current.tm_year) { now_time -= ONE_DAY * days_in_year(¤t, -1); } else if (month > current.tm_mon + 1) { now_time += ONE_DAY * days_in_month(¤t, 0); } else if (month < current.tm_mon + 1) { now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (day > current.tm_mday) { now_time += ONE_DAY; } else if (day < current.tm_mday) { now_time -= ONE_DAY; } else { break; } current = *localtime(&now_time); } } dlg_button_layout(buttons, &mincols); #ifdef KEY_RESIZE retry: #endif dlg_auto_size(title, prompt, &height, &width, 0, mincols); height += MIN_HIGH - 1; dlg_print_size(height, width); dlg_ctl_size(height, width); dialog = dlg_new_window(height, width, dlg_box_y_ordinate(height), dlg_box_x_ordinate(width)); dlg_register_window(dialog, "calendar", binding); dlg_register_buttons(dialog, "calendar", buttons); /* mainbox */ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); (void) wattrset(dialog, dialog_attr); /* text mainbox */ dlg_print_autowrap(dialog, prompt, height, width); /* compute positions of day, month and year boxes */ memset(&dy_box, 0, sizeof(dy_box)); memset(&mn_box, 0, sizeof(mn_box)); memset(&yr_box, 0, sizeof(yr_box)); if (init_object(&dy_box, dialog, (width - DAY_WIDE) / 2, 1 + (height - (DAY_HIGH + BTN_HIGH + (5 * MARGIN))), DAY_WIDE, DAY_HIGH + 1, draw_day, 'D') < 0 || DrawObject(&dy_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } if (init_object(&mn_box, dialog, dy_box.x, dy_box.y - (HDR_HIGH + 2 * MARGIN), (DAY_WIDE / 2) - MARGIN, HDR_HIGH, draw_month, 'M') < 0 || DrawObject(&mn_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } if (init_object(&yr_box, dialog, dy_box.x + mn_box.width + 2, mn_box.y, mn_box.width, mn_box.height, draw_year, 'Y') < 0 || DrawObject(&yr_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } dlg_trace_win(dialog); while (result == DLG_EXIT_UNKNOWN) { BOX *obj = (state == sDAY ? &dy_box : (state == sMONTH ? &mn_box : (state == sYEAR ? &yr_box : 0))); button = (state < 0) ? 0 : state; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (obj != 0) dlg_set_focus(dialog, obj->window); key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if (fkey && (key >= DLGK_MOUSE(KEY_MIN) && key <= DLGK_MOUSE(KEY_MAX))) { key = dlg_lookup_key(dialog, key - M_EVENT, &fkey); } if ((key2 = dlg_char_to_button(key, buttons)) >= 0) { result = key2; } else if (fkey) { /* handle function-keys */ switch (key) { case DLGK_MOUSE('D'): state = sDAY; break; case DLGK_MOUSE('M'): state = sMONTH; break; case DLGK_MOUSE('Y'): state = sYEAR; break; case DLGK_ENTER: result = dlg_enter_buttoncode(button); break; case DLGK_FIELD_PREV: state = dlg_prev_ok_buttonindex(state, sMONTH); break; case DLGK_FIELD_NEXT: state = dlg_next_ok_buttonindex(state, sMONTH); break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif default: step = 0; key2 = -1; if (is_DLGK_MOUSE(key)) { if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) { result = key2; break; } else if (key >= DLGK_MOUSE(KEY_MAX)) { state = sDAY; obj = &dy_box; key2 = 1; step = (key - DLGK_MOUSE(KEY_MAX) - day_cell_number(¤t)); } } if (obj != 0) { if (key2 < 0) step = next_or_previous(key, (obj == &dy_box)); if (step != 0) { struct tm old = current; /* see comment regarding mktime -TD */ if (obj == &dy_box) { now_time += ONE_DAY * step; } else if (obj == &mn_box) { if (step > 0) now_time += ONE_DAY * days_in_month(¤t, 0); else now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (obj == &yr_box) { if (step > 0) now_time += (ONE_DAY * days_in_year(¤t, 0)); else now_time -= (ONE_DAY * days_in_year(¤t, -1)); } current = *localtime(&now_time); if (obj != &dy_box && (current.tm_mday != old.tm_mday || current.tm_mon != old.tm_mon || current.tm_year != old.tm_year)) DrawObject(&dy_box); if (obj != &mn_box && current.tm_mon != old.tm_mon) DrawObject(&mn_box); if (obj != &yr_box && current.tm_year != old.tm_year) DrawObject(&yr_box); (void) DrawObject(obj); } } else if (state >= 0) { if (next_or_previous(key, FALSE) < 0) state = dlg_prev_ok_buttonindex(state, sMONTH); else if (next_or_previous(key, FALSE) > 0) state = dlg_next_ok_buttonindex(state, sMONTH); } break; } } } #define DefaultFormat(dst, src) \ sprintf(dst, "%02d/%02d/%0d", \ src.tm_mday, src.tm_mon + 1, src.tm_year + 1900) #ifdef HAVE_STRFTIME if (dialog_vars.date_format != 0) { size_t used = strftime(buffer, sizeof(buffer) - 1, dialog_vars.date_format, ¤t); if (used == 0 || *buffer == '\0') DefaultFormat(buffer, current); } else #endif DefaultFormat(buffer, current); dlg_add_result(buffer); dlg_add_separator(); return CleanupResult(result, dialog, prompt, &save_vars); }
double Hebrew::days_in_year () const { return days_in_year (rep_.d_year ()); }
/* * Display a dialog box for entering a date */ int dialog_calendar(const char *title, const char *subtitle, int height, int width, int day, int month, int year) { BOX dy_box, mn_box, yr_box; int fkey; int key = 0; int key2; int step; int button = 0; int result = DLG_EXIT_UNKNOWN; WINDOW *dialog; time_t now_time = time((time_t *) 0); struct tm current; STATES state = 0; const char **buttons = dlg_ok_labels(); char *prompt = strclone(subtitle); dlg_does_output(); now_time = time((time_t *) 0); current = *localtime(&now_time); if (day < 0) day = current.tm_mday; if (month < 0) month = current.tm_mon + 1; if (year < 0) year = current.tm_year + 1900; /* compute a struct tm that matches the day/month/year parameters */ if (((year -= 1900) > 0) && (year < 200)) { /* ugly, but I'd like to run this on older machines w/o mktime -TD */ for (;;) { if (year > current.tm_year) { now_time += ONE_DAY * days_in_year(¤t, 0); } else if (year < current.tm_year) { now_time -= ONE_DAY * days_in_year(¤t, -1); } else if (month > current.tm_mon + 1) { now_time += ONE_DAY * days_in_month(¤t, 0); } else if (month < current.tm_mon + 1) { now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (day > current.tm_mday) { now_time += ONE_DAY; } else if (day < current.tm_mday) { now_time -= ONE_DAY; } else { break; } current = *localtime(&now_time); } } auto_size(title, prompt, &height, &width, 0, 0); height += MIN_HIGH; if (width < MIN_WIDE) width = MIN_WIDE; print_size(height, width); ctl_size(height, width); /* FIXME: how to make this resizable? */ dialog = new_window(height, width, box_y_ordinate(height), box_x_ordinate(width)); draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); draw_bottom_box(dialog); draw_title(dialog, title); wattrset(dialog, dialog_attr); print_autowrap(dialog, prompt, height, width); /* compute positions of day, month and year boxes */ memset(&dy_box, 0, sizeof(dy_box)); memset(&mn_box, 0, sizeof(mn_box)); memset(&yr_box, 0, sizeof(yr_box)); if (init_object(&dy_box, dialog, (width - DAY_WIDE) / 2, (height - (DAY_HIGH + BTN_HIGH + (4 * MARGIN))), DAY_WIDE, DAY_HIGH + (2 * MARGIN), draw_day, 'D') < 0 || DrawObject(&dy_box) < 0) return DLG_EXIT_ERROR; if (init_object(&mn_box, dialog, dy_box.x, dy_box.y - (HDR_HIGH + 2 * MARGIN), (DAY_WIDE / 2) - MARGIN, HDR_HIGH, draw_month, 'M') < 0 || DrawObject(&mn_box) < 0) return DLG_EXIT_ERROR; if (init_object(&yr_box, dialog, dy_box.x + mn_box.width + 2, mn_box.y, mn_box.width, mn_box.height, draw_year, 'Y') < 0 || DrawObject(&yr_box) < 0) return DLG_EXIT_ERROR; while (result == DLG_EXIT_UNKNOWN) { BOX *obj = (state == sDAY ? &dy_box : (state == sMONTH ? &mn_box : (state == sYEAR ? &yr_box : 0))); button = (state < 0) ? 0 : state; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (obj != 0) dlg_set_focus(dialog, obj->window); key = mouse_wgetch(dialog, &fkey); if ((key2 = dlg_char_to_button(key, buttons)) >= 0) { result = key2; } else { /* handle non-functionkeys */ if (!fkey) { fkey = TRUE; switch (key) { case ' ': case '\n': case '\r': key = KEY_ENTER; break; case TAB: key = KEY_RIGHT; break; case CHR_PREVIOUS: case CHR_NEXT: case CHR_BACKSPACE: case 'h': case 'j': case 'k': case 'l': /* treat these as function-keys */ break; case ESC: result = DLG_EXIT_ESC; fkey = FALSE; break; default: fkey = FALSE; break; } } /* handle functionkeys */ if (fkey) { switch (key) { case M_EVENT + 'D': state = sDAY; break; case M_EVENT + 'M': state = sMONTH; break; case M_EVENT + 'Y': state = sYEAR; break; case KEY_ENTER: result = dlg_ok_buttoncode(button); break; case KEY_LEFT: case KEY_BTAB: state = dlg_prev_ok_buttonindex(state, sMONTH); break; case KEY_RIGHT: state = dlg_next_ok_buttonindex(state, sMONTH); break; default: step = 0; key2 = -1; if (key >= M_EVENT) { if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) { result = key2; break; } else if (key >= (M_EVENT + KEY_MAX)) { state = sDAY; obj = &dy_box; key2 = 1; step = (key - (M_EVENT + KEY_MAX) - day_cell_number(¤t)); } } if (obj != 0) { if (key2 < 0) step = next_or_previous(key, (obj == &dy_box)); if (step != 0) { struct tm old = current; /* see comment regarding mktime -TD */ if (obj == &dy_box) { now_time += ONE_DAY * step; } else if (obj == &mn_box) { if (step > 0) now_time += ONE_DAY * days_in_month(¤t, 0); else now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (obj == &yr_box) { if (step > 0) now_time += (ONE_DAY * days_in_year(¤t, 0)); else now_time -= (ONE_DAY * days_in_year(¤t, -1)); } current = *localtime(&now_time); if (obj != &dy_box && (current.tm_mday != old.tm_mday || current.tm_mon != old.tm_mon || current.tm_year != old.tm_year)) DrawObject(&dy_box); if (obj != &mn_box && current.tm_mon != old.tm_mon) DrawObject(&mn_box); if (obj != &yr_box && current.tm_year != old.tm_year) DrawObject(&yr_box); (void) DrawObject(obj); } } break; } } } } del_window(dialog); sprintf(dialog_vars.input_result, "%02d/%02d/%0d\n", current.tm_mday, current.tm_mon + 1, current.tm_year + 1900); mouse_free_regions(); free(prompt); return result; }
static int fill_iso8601_timestamp(int32_t timestamp, int32_t milli, char* buffer, int* length) { int16_t year; int8_t month, month_length; int32_t day; int8_t hour, minute, second; if (*length < SIZE_ISO_8601) { *length = SIZE_ISO_8601; return E_BUFFER_TOO_SMALL; } second = timestamp % 60; timestamp /= 60; // now it is minutes minute = timestamp % 60; timestamp /= 60; // now it is hours hour = timestamp % 24; timestamp /= 24; // now it is days year = 0; day = 0; while ((day += days_in_year(year)) <= timestamp) { year++; } day -= days_in_year(year); timestamp -= day; // now it is days in this year, starting at 0 day = 0; month_length = 0; for (month = 0; month < 12; month++) { if (month == 1) { // February month_length = is_leap_year(year) ? 29 : 28; } else { month_length = MONTH_DAYS[month]; } if (timestamp >= month_length) { timestamp -= month_length; } else { break; } } year = 1970 + year; month++; // offset by 1 day = timestamp + 1; int i = 0, j = 0; // NOTE: It seems the snprintf implementation in Arduino has bugs, // we have to manually piece the string together here. #define INT_TO_STR(v_, width_) \ for (j = 0; j < (width_); j++) { \ buffer[i + (width_) - 1 - j] = '0' + ((v_) % 10); \ (v_) /= 10; \ } \ i += (width_) INT_TO_STR(year, 4); buffer[i++] = '-'; INT_TO_STR(month, 2); buffer[i++] = '-'; INT_TO_STR(day, 2); buffer[i++] = 'T'; INT_TO_STR(hour, 2); buffer[i++] = ':'; INT_TO_STR(minute, 2); buffer[i++] = ':'; INT_TO_STR(second, 2); buffer[i++] = '.'; INT_TO_STR(milli, 3); buffer[i++] = 'Z'; buffer[i++] = '\0'; #undef INT_TO_STR *length = i; return E_OK; }
Parsed* _parse_iso8601_datetime(char *str, Parsed *parsed) { char* c; int monthday = 0; int week = 0; int weekday = 1; int ordinal; int tz_sign = 0; int leap = 0; int separators = 0; int time = 0; int has_hour = 0; int i; int j; // Assuming date only for now parsed->is_date = 1; c = str; for (i = 0; i < 4; i++) { if (*c >= '0' && *c <= '9') { parsed->year = 10 * parsed->year + *c++ - '0'; } else { parsed->error = PARSER_INVALID_ISO8601; return NULL; } } leap = is_leap(parsed->year); // Optional separator if (*c == '-') { separators++; c++; } // Checking for week dates if (*c == 'W') { c++; i = 0; while (*c != '\0' && *c != ' ' && *c != 'T') { if (*c == '-') { separators++; c++; continue; } week = 10 * week + *c++ - '0'; i++; } switch (i) { case 2: // Only week number break; case 3: // Week with weekday if (!(separators == 0 || separators == 2)) { // We should have 2 or no separator parsed->error = PARSER_INVALID_WEEK_DATE; return NULL; } weekday = week % 10; week /= 10; break; default: // Any other case is wrong parsed->error = PARSER_INVALID_WEEK_DATE; return NULL; } // Checks if (week > 53 || week > 52 && !is_long_year(parsed->year)) { parsed->error = PARSER_INVALID_WEEK_NUMBER; return NULL; } if (weekday > 7) { parsed->error = PARSER_INVALID_WEEKDAY_NUMBER; return NULL; } // Calculating ordinal day ordinal = week * 7 + weekday - (week_day(parsed->year, 1, 4) + 3); if (ordinal < 1) { // Previous year ordinal += days_in_year(parsed->year - 1); parsed->year -= 1; leap = is_leap(parsed->year); } if (ordinal > days_in_year(parsed->year)) { // Next year ordinal -= days_in_year(parsed->year); parsed->year += 1; leap = is_leap(parsed->year); } for (j = 1; j < 14; j++) { if (ordinal <= MONTHS_OFFSETS[leap][j]) { parsed->day = ordinal - MONTHS_OFFSETS[leap][j - 1]; parsed->month = j - 1; break; } } } else { // At this point we need to check the number // of characters until the end of the date part // (or the end of the string). // // If two, we have only a month if there is a separator, it may be a time otherwise. // If three, we have an ordinal date. // If four, we have a complete date i = 0; while (*c != '\0' && *c != ' ' && *c != 'T') { if (*c == '-') { separators++; c++; continue; } if (!(*c >= '0' && *c <='9')) { parsed->error = PARSER_INVALID_DATE; return NULL; } monthday = 10 * monthday + *c++ - '0'; i++; } switch (i) { case 0: // No month/day specified (only a year) break; case 2: if (!separators) { // The date looks like 201207 // which is invalid for a date // But it might be a time in the form hhmmss parsed->ambiguous = 1; } parsed->month = monthday; break; case 3: // Ordinal day if (separators > 1) { parsed->error = PARSER_INVALID_DATE; return NULL; } if (monthday < 1 || monthday > MONTHS_OFFSETS[leap][13]) { parsed->error = PARSER_INVALID_ORDINAL_DAY_FOR_YEAR; return NULL; } for (j = 1; j < 14; j++) { if (monthday <= MONTHS_OFFSETS[leap][j]) { parsed->day = monthday - MONTHS_OFFSETS[leap][j - 1]; parsed->month = j - 1; break; } } break; case 4: // Month and day parsed->month = monthday / 100; parsed->day = monthday % 100; break; default: parsed->error = PARSER_INVALID_MONTH_OR_DAY; return NULL; } } // Checks if (separators && !monthday && !week) { parsed->error = PARSER_INVALID_DATE; return NULL; } if (parsed->month > 12) { parsed->error = PARSER_INVALID_MONTH; return NULL; } if (parsed->day > DAYS_PER_MONTHS[leap][parsed->month]) { parsed->error = PARSER_INVALID_DAY_FOR_MONTH; return NULL; } separators = 0; if (*c == 'T' || *c == ' ') { if (parsed->ambiguous) { parsed->error = PARSER_INVALID_DATE; return NULL; } // We have time so we have a datetime parsed->is_datetime = 1; parsed->is_date = 0; c++; // Grabbing time information i = 0; while (*c != '\0' && *c != '.' && *c != ',' && *c != 'Z' && *c != '+' && *c != '-') { if (*c == ':') { separators++; c++; continue; } if (!(*c >= '0' && *c <='9')) { parsed->error = PARSER_INVALID_TIME; return NULL; } time = 10 * time + *c++ - '0'; i++; } switch (i) { case 2: // Hours only if (separators > 0) { // Extraneous separators parsed->error = PARSER_INVALID_TIME; return NULL; } parsed->hour = time; has_hour = 1; break; case 4: // Hours and minutes if (separators > 1) { // Extraneous separators parsed->error = PARSER_INVALID_TIME; return NULL; } parsed->hour = time / 100; parsed->minute = time % 100; has_hour = 1; break; case 6: // Hours, minutes and seconds if (!(separators == 0 || separators == 2)) { // We should have either two separators or none parsed->error = PARSER_INVALID_TIME; return NULL; } parsed->hour = time / 10000; parsed->minute = time / 100 % 100; parsed->second = time % 100; has_hour = 1; break; default: // Any other case is wrong parsed->error = PARSER_INVALID_TIME; return NULL; } // Checks if (parsed->hour > 23) { parsed->error = PARSER_INVALID_HOUR; return NULL; } if (parsed->minute > 59) { parsed->error = PARSER_INVALID_MINUTE; return NULL; } if (parsed->second > 59) { parsed->error = PARSER_INVALID_SECOND; return NULL; } // Subsecond if (*c == '.' || *c == ',') { c++; time = 0; i = 0; while (*c != '\0' && *c != 'Z' && *c != '+' && *c != '-') { if (!(*c >= '0' && *c <='9')) { parsed->error = PARSER_INVALID_SUBSECOND; return NULL; } time = 10 * time + *c++ - '0'; i++; } // adjust to microseconds if (i > 6) { parsed->microsecond = time / pow(10, i - 6); } else if (i <= 6) { parsed->microsecond = time * pow(10, 6 - i); } } // Timezone if (*c == 'Z') { parsed->has_offset = 1; c++; } else if (*c == '+' || *c == '-') { tz_sign = 1; if (*c == '-') { tz_sign = -1; } parsed->has_offset = 1; c++; i = 0; time = 0; separators = 0; while (*c != '\0') { if (*c == ':') { separators++; c++; continue; } if (!(*c >= '0' && *c <= '9')) { parsed->error = PARSER_INVALID_TZ_OFFSET; return NULL; } time = 10 * time + *c++ - '0'; i++; } switch (i) { case 2: // hh Format if (separators) { // Extraneous separators parsed->error = PARSER_INVALID_TZ_OFFSET; return NULL; } parsed->offset = tz_sign * (time * 3600); break; case 4: // hhmm Format if (separators > 1) { // Extraneous separators parsed->error = PARSER_INVALID_TZ_OFFSET; return NULL; } parsed->offset = tz_sign * ((time / 100 * 3600) + (time % 100 * 60)); break; default: // Wrong format parsed->error = PARSER_INVALID_TZ_OFFSET; return NULL; } } } // At this point we should be at the end of the string // If not, the string is invalid if (*c != '\0') { parsed->error = PARSER_INVALID_ISO8601; return NULL; } return parsed; }
int date::days_in_year() const { return days_in_year(m_year); }