/* * 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_defaultno_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_box(dialog, 0, 0, height, width, dialog_attr, border_attr); dlg_draw_bottom_box(dialog); dlg_draw_title(dialog, title); 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); } 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); }
void calendar_single_draw(Layer* layer, GContext* context, int16_t offset) { // Get the current date RootData* data = window_get_user_data(layer_get_window(layer)); time_t t = data->curTime; struct tm* localTime = localtime(&t); char month[20]; strftime(month, 20, "%B %Y", localTime); if(data->days_in_use_valid.month != (unsigned int)localTime->tm_mon+1 || data->days_in_use_valid.year != (unsigned int)(localTime->tm_year + 1900)) { APP_LOG(APP_LOG_LEVEL_INFO, "Requesting new data. %d %d -> %d %d", data->days_in_use_valid.month, data->days_in_use_valid.year, localTime->tm_mon, localTime->tm_year); int rv = 0; rv = devinterface_get_days_used(localTime->tm_mon, localTime->tm_year, daysused_returned, data); if(rv != DEV_STAT_OK) APP_LOG(APP_LOG_LEVEL_WARNING, "devinterface_get_days_used failed %d", rv); } // Get the first day of the month (Mon-Sun) // Get the current day and day of week int curDay = localTime->tm_mday; int dow = localTime->tm_wday; // What's the offset into dow? // Ignoring weeks, this will give us the number of days // since the first of the month int curDowOffset = (curDay - 1 + WEEK_START_OFFSET) % 7; // We then subtract that from the current day of the week // which will yield the dow of the first day of the month. dow -= curDowOffset; if(dow < 0) dow += 7; // Get the number of days to draw int days_month = days_in_month(localTime->tm_mon + 1, localTime->tm_year + 1900); // How many weeks do we need to show? // How many days are there, including the leadin? int totalSlots = (days_month + dow); int lines = totalSlots / 7; // I'm not resorting to the FPU. Check if it had a fractional part if(lines * 7 != totalSlots) lines++; // Create the bounding box for the period GRect contextBound = layer_get_frame(layer); GRect textBounding = contextBound; textBounding.origin.y += offset + MONTHPANE_Y_OFFSET; textBounding.size.h = MONTHPANE_HEIGHT; // Put up the current period graphics_draw_text(context, month, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), textBounding, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); // Compute the height of the calendar box int calHeight = contextBound.size.h - CALENDARPANE_TOP - CALENDARPANE_Y_MARGIN; int calWidth = contextBound.size.w - (CALENDARPANE_X_MARGIN*2); // Draw the calendar box // Top line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset}); // Bottom line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + calHeight + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + calHeight + offset}); // Left line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset + calHeight}); // Right line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset + calHeight}); // And now the vertical subdivisions. There needs to be 7. int vertSubDiv = calWidth / 7; for(int i = 1; i < 7; i++) { graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN + vertSubDiv*i, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + vertSubDiv*i, CALENDARPANE_TOP + offset + calHeight}); } // And now the horizontal subdivisions. int horizSubDiv = calHeight / lines; for(int i = 1; i < lines; i++) { graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset + horizSubDiv*i}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset + horizSubDiv*i}); } // Now draw the days for(int day = 1; day <= days_month; day++) { int x = (day-1+dow) % 7; int y = (day-1+dow) / 7; char dayStr[3]; snprintf(dayStr, 3, "%d", day); // Is this the current day? if(day == localTime->tm_mday) { // Paint it white GRect dayRectFill; dayRectFill.origin.x = (x * vertSubDiv) + CALENDARPANE_X_MARGIN; dayRectFill.origin.y = (y * horizSubDiv) + CALENDARPANE_TOP + offset; dayRectFill.size.h = horizSubDiv; dayRectFill.size.w = vertSubDiv; graphics_context_set_fill_color(context, GColorWhite); graphics_context_set_text_color(context, GColorBlack); graphics_fill_rect(context, dayRectFill, 0, GCornerNone); } GRect dayRect; dayRect.origin.x = (x * vertSubDiv) + CALENDARPANE_X_MARGIN + CALENDARPANE_NUMBER_X_PAD; dayRect.origin.y = (y * horizSubDiv) + CALENDARPANE_TOP + offset; dayRect.size.h = horizSubDiv; dayRect.size.w = vertSubDiv; if(data->days_in_use_valid.month == (unsigned int)localTime->tm_mon+1 && data->days_in_use_valid.year == (unsigned int)(localTime->tm_year + 1900)) { if(data->days_in_use & (1 << (day - 1))) graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); else graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); } else { graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); } if(day == localTime->tm_mday) { graphics_context_set_fill_color(context, GColorBlack); graphics_context_set_text_color(context, GColorWhite); } } }
/* * Draw the day-of-month selection box */ static int draw_day(BOX * data, struct tm *current) { int cell_wide = MON_WIDE; int y, x, this_x = 0; int save_y = 0, save_x = 0; int day = current->tm_mday; int mday; int week; int last = days_in_month(current, 0); int prev = days_in_month(current, -1); werase(data->window); dlg_draw_box(data->parent, data->y - MARGIN, data->x - MARGIN, data->height + (2 * MARGIN), data->width + (2 * MARGIN), menubox_border_attr, menubox_attr); /* border of daybox */ wattrset(data->window, menubox_attr); /* daynames headline */ for (x = 0; x < 7; x++) { mvwprintw(data->window, 0, (x + 1) * cell_wide, "%*.*s ", cell_wide - 1, cell_wide - 1, nameOfDayOfWeek(x)); } mday = ((6 + current->tm_mday - current->tm_wday) % 7) - 7; if (mday <= -7) mday += 7; /* mday is now in the range -6 to 0. */ week = (current->tm_yday + 6 + mday - current->tm_mday) / 7; for (y = 1; mday < last; y++) { wattrset(data->window, menubox_attr); /* weeknumbers headline */ mvwprintw(data->window, y, 0, "%*d ", cell_wide - 1, ++week); for (x = 0; x < 7; x++) { this_x = 1 + (x + 1) * cell_wide; ++mday; if (wmove(data->window, y, this_x) == ERR) continue; wattrset(data->window, item_attr); /* not selected days */ if (mday == day) { wattrset(data->window, item_selected_attr); /* selected day */ save_y = y; save_x = this_x; } if (mday > 0) { if (mday <= last) { wprintw(data->window, "%*d", cell_wide - 2, mday); } else if (mday == day) { wprintw(data->window, "%*d", cell_wide - 2, mday - last); } } else if (mday == day) { wprintw(data->window, "%*d", cell_wide - 2, mday + prev); } } wmove(data->window, save_y, save_x); } /* just draw arrows - scrollbar is unsuitable here */ dlg_draw_arrows(data->parent, TRUE, TRUE, data->x + ARROWS_COL, data->y - 1, data->y + data->height); return 0; }
int weeks_in_month(year_t year, month_t month) { int start = start_of_month(year, month); int days = days_in_month(year, month); return ((start + days)-1) / 7 + 1; }
/** * Parse the time columns of a record in a CSV file and set the record time. * * If an error occurs in this function it will be appended to the log and * error mail messages, and the process status will be set appropriately. * * @param csv pointer to the CSVParser structure * @param record_index record index * * @retval 1 if successful * @retval 0 if invalid time format * @retval -1 if an error occurred */ int _csv_parse_record_time( CSVParser *csv, int record_index) { char *time_string; int status; int tci, fi; RETimeList *tc_patterns; RETimeRes match; RETimeRes result; int used_file_date; timeval_t rec_time; timeval_t prev_time; int tro_interval; double delta_t; struct tm gmt; /* Get the time column indexes */ if (!csv->tc_index) { if (!_csv_create_tc_index(csv)) { return(-1); } } /* Parse time strings and merge results */ for (tci = 0; tci < csv->ntc; ++tci) { fi = csv->tc_index[tci]; tc_patterns = csv->tc_patterns[tci]; /* Make sure this is a valid field index */ if (fi < 0 || fi > csv->nfields) { ERROR( DSPROC_LIB_NAME, "Time column index '%d' is out of range [0, %d].\n", fi, csv->nfields); dsproc_set_status(DSPROC_ECSVPARSER); return(-1); } time_string = csv->values[fi][record_index]; /* Parse time string */ status = retime_list_execute(tc_patterns, time_string, &match); if (status < 0) { ERROR( DSPROC_LIB_NAME, "Time string pattern match failed for record %d.\n", record_index + 1); dsproc_set_status(DSPROC_ECSVPARSER); return(-1); } else if (status == 0) { DSPROC_BAD_RECORD_WARNING(csv->file_name, csv->nrecs, "Record time format '%s' does not match '%s'\n", time_string, tc_patterns->retimes[tc_patterns->npatterns - 1]->tspattern); return(0); } /* Merge results */ if (tci == 0) { result = match; } else { if (match.year != -1) result.year = match.year; if (match.month != -1) result.month = match.month; if (match.mday != -1) result.mday = match.mday; if (match.hour != -1) result.hour = match.hour; if (match.min != -1) result.min = match.min; if (match.sec != -1) result.sec = match.sec; if (match.usec != -1) result.usec = match.usec; if (match.century != -1) result.century = match.century; if (match.yy != -1) result.yy = match.yy; if (match.yday != -1) result.yday = match.yday; if (match.secs1970 != -1) result.secs1970 = match.secs1970; } } if (result.secs1970 != -1) { csv->tvs[record_index].tv_sec = result.secs1970; csv->tvs[record_index].tv_usec = (result.usec == -1) ? 0 : result.usec; csv->tvs[record_index].tv_sec += csv->time_offset; csv->tvs[record_index].tv_sec += csv->tro_offset; return(1); } /* Check if we need to use the date from the file name */ used_file_date = 0; if (csv->ft_patterns) { if (!csv->ft_result) { csv->ft_result = calloc(1, sizeof(RETimeRes)); if (!csv->ft_result) { ERROR( DSPROC_LIB_NAME, "Memory allocation error creating file name RETimeRes structure\n"); dsproc_set_status(DSPROC_ECSVPARSER); return(-1); } status = dsproc_get_csv_file_name_time(csv, csv->file_name, csv->ft_result); if (status < 0) return(-1); } if (result.year == -1) { if (csv->ft_result->year != -1) { result.year = csv->ft_result->year; used_file_date = 1; } else { ERROR( DSPROC_LIB_NAME, "Could not determine record time\n" " -> year not found in record or file name time patterns\n"); dsproc_set_status(DSPROC_ECSVPARSER); return(-1); } } if (result.month == -1) { if (result.yday != -1) { yday_to_mday(result.yday, &(result.year), &(result.month), &(result.mday)); } else if (csv->ft_result->month != -1) { result.month = csv->ft_result->month; used_file_date = 2; } else if (csv->ft_result->yday != -1) { yday_to_mday(csv->ft_result->yday, &(result.year), &(result.month), &(result.mday)); used_file_date = 3; } } if (result.mday == -1) { if (csv->ft_result->mday != -1) { result.mday = csv->ft_result->mday; used_file_date = 3; } } } else { /* Verify that the year was found */ if (result.year == -1) { ERROR( DSPROC_LIB_NAME, "Could not determine record time\n" " -> year not found in record time pattern\n"); dsproc_set_status(DSPROC_ECSVPARSER); return(-1); } } rec_time = retime_get_timeval(&result); rec_time.tv_sec += csv->time_offset; rec_time.tv_sec += csv->tro_offset; /* Check for time rollovers if the file date was used */ if (used_file_date && record_index > 0) { prev_time = csv->tvs[record_index - 1]; if (TV_LT(rec_time, prev_time)) { switch (used_file_date) { case 1: /* yearly */ gmtime_r(&(prev_time.tv_sec), &gmt); if (IS_LEAP_YEAR(gmt.tm_year + 1900)) { tro_interval = 366 * 86400; } else { tro_interval = 365 * 86400; } if (!csv->tro_threshold) { csv->tro_threshold = 86400; } break; case 2: /* monthly */ gmtime_r(&(prev_time.tv_sec), &gmt); tro_interval = days_in_month(gmt.tm_year + 1900, gmt.tm_mon + 1) * 86400; if (!csv->tro_threshold) { csv->tro_threshold = 43200; } break; default: /* daily */ tro_interval = 86400; if (!csv->tro_threshold) { csv->tro_threshold = 3600; } } delta_t = (TV_DOUBLE(rec_time) + tro_interval) - TV_DOUBLE(prev_time); if ((delta_t > 0) && (delta_t < csv->tro_threshold)) { rec_time.tv_sec += tro_interval; csv->tro_offset += tro_interval; } } } if (record_index > 0) { prev_time = csv->tvs[record_index - 1]; } csv->tvs[record_index] = rec_time; return(1); }
/* Month draw */ void month_draw(void) { const char *name = month_to_string(SEL.month); const int start = start_of_month(SEL.year, SEL.month); const int days = days_in_month(SEL.year, SEL.month); const int weeks = weeks_in_month(SEL.year, SEL.month); const int hdr = COMPACT ? 3 : 4; const float midpt = (float)COLS/2.0 - (strlen(name) + 1 + 4)/2.0; const float hstep = (float)(COLS-1)/7.0; const float vstep = (float)(LINES-2-hdr+COMPACT)/weeks; /* Load cal data */ cal_load(SEL.year, SEL.month, 0, days); /* Print Header */ if (COMPACT) wattron(win, A_REVERSE | A_BOLD); if (COMPACT) mvwhline(win, 0, 0, ' ' | A_REVERSE | A_BOLD, COLS); if (COMPACT) mvwhline(win, 1, 0, ' ' | A_REVERSE | A_BOLD, COLS); mvwprintw(win, 0, midpt, "%s %d", name, SEL.year); for (int d = 0; d < 7; d++) { const char *str = hstep >= 10 ? day_to_string(d+SUN) : day_to_str(d+SUN); mvwprintw(win, 1, ROUND(1+d*hstep), "%s", str); } if (COMPACT) wattroff(win, A_REVERSE | A_BOLD); if (!COMPACT) mvwhline(win, 2, 0, ACS_HLINE, COLS); /* Print days */ for (int d = 0; d < days; d++) { int row = (start + d) / 7; int col = (start + d) % 7; if (d == SEL.day) wattron(win, A_BOLD); mvwprintw(win, ROUND(hdr+row*vstep), ROUND(1+col*hstep), "%d", d+1); if (d == SEL.day) wattroff(win, A_BOLD); } /* Print events */ event_t *event = EVENTS; for (int d = 0; d < days; d++) { int y = ROUND(hdr+(((start + d) / 7) )*vstep); int e = ROUND(hdr+(((start + d) / 7)+1)*vstep)-2; int x = ROUND(1 +(((start + d) % 7) )*hstep)+3; int w = ROUND(1 +(((start + d) % 7)+1)*hstep)-x-1; while (event && before(&event->start, SEL.year, SEL.month, d, 24, 0)) { if (!before(&event->start, SEL.year, SEL.month, d, 0, 0)){ if (y == e) mvwhline(win, y, x-3, ACS_DARROW, 2); if (y <= e) event_line(win, event, y, x, w, 0); y++; } event = event->next; } } /* Print lines */ for (int w = 1; w < weeks; w++) mvwhline(win, ROUND(hdr-1+w*vstep), 1, ACS_HLINE, COLS-2); for (int d = 1; d < 7; d++) { int top = d >= start ? 0 : 1; int bot = d <= (start+days-1)%7+1 ? weeks : weeks-1; mvwvline(win, ROUND(hdr+top*vstep), ROUND(d*hstep), ACS_VLINE, (bot-top)*vstep); for (int w = 1; w < weeks; w++) { int chr = w == top ? ACS_TTEE : w == bot ? ACS_BTEE : ACS_PLUS; mvwaddch(win, ROUND(hdr-1+w*vstep), ROUND(d*hstep), chr); } } /* Draw today */ int col = day_of_week(SEL.year, SEL.month, SEL.day); int row = (start+SEL.day) / 7; int l = ROUND((col+0)*hstep); int r = ROUND((col+1)*hstep); int t = ROUND((row+0)*vstep+hdr-1); int b = ROUND((row+1)*vstep+hdr-1); mvwvline_set(win, t, l, WACS_T_VLINE, b-t); mvwvline_set(win, t, r, WACS_T_VLINE, b-t); mvwhline_set(win, t, l, WACS_T_HLINE, r-l); mvwhline_set(win, b, l, WACS_T_HLINE, r-l); mvwadd_wch(win, t, l, WACS_T_ULCORNER); mvwadd_wch(win, t, r, WACS_T_URCORNER); mvwadd_wch(win, b, l, WACS_T_LLCORNER); mvwadd_wch(win, b, r, WACS_T_LRCORNER); }
/*--------------------------- * Start of HydroExpDist.c *---------------------------*/ int hydroexpdist(double pvals[31],int mnth) { double dumdbl, sumx, sumxx; double stda, stdb; double da[ntot], db[ntot], dc[ntot]; int ii, kk, err; /*------------------------ * Initialize variables *------------------------*/ err = 0; sumx = 0.0; sumxx = 0.0; /*---------------------------------------------------------------- * Transform more than the number of needed values * this allows for the removal of outliers * Pretend to be making a two sided distribution with mean == 0 * therefore: sumx == 0 *----------------------------------------------------------------*/ for( ii=0; ii<ntot; ii++) { dumdbl = ranarray[nran]; nran++; if( dumdbl < 0.0 ) dumdbl = -dumdbl; da[ii] = pow(exp(dumdbl),Pexponent[ep]); sumxx += sq(da[ii]); } /*------------------------------------------------------------------------- * Calculate the standard deviation of the 1st round of numbers (da[ii]) *-------------------------------------------------------------------------*/ stda = sqrt( sumxx/ntot); /*------------------------------------------------------------------- * Normalize the values to the input Standard Deviation (1st Pass) * remove outliers (or save good values) * find new Standard Deviation *-------------------------------------------------------------------*/ sumx = 0.0; sumxx = 0.0; kk = 0; for( ii=0; ii<ntot; ii++ ) { dumdbl = (Pmassbal[ep]*Pnomstd[mnth][ep]/stda)*da[ii]; if( 0 < dumdbl && dumdbl < Prange[ep]*Pmassbal[ep]*Pnomstd[mnth][ep] ) { db[kk] = dumdbl; sumxx += sq(db[kk]); kk++; } } /*---------------------------------------------------------------------- * Calculate the Standard Deviation of the generated numbers (db[ii]) *----------------------------------------------------------------------*/ stdb = sqrt( sumxx/kk); /*------------------------------------------------------------------- * Normalize the values to the input Standard Deviation (2nd Pass) *-------------------------------------------------------------------*/ for( ii=0; ii<kk; ii++) dc[ii] = (Pmassbal[ep]*Pnomstd[mnth][ep]/stdb)*db[ii]; /*-------------------------------------------- * make sure we return enough usable points *--------------------------------------------*/ //if( kk < daysim[mnth] ) { if ( kk < days_in_month(mnth) ) { fprintf( stderr, " HydroExpDist ERROR: Not enough points generated for the non-normal distribution.\n"); fprintf( stderr, " Increase NTOT in expdist.c \n"); // fprintf( stderr, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth,daysim[mnth]); fprintf( stderr, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth,days_in_month(mnth)); fprintf( stderr, " started ntot \t = %d \n", ntot); fprintf( stderr, " Generated (kk) \t = %d \n", kk); // fprintf( stderr, " needed daysim \t = %d \n", daysim[mnth]); fprintf( stderr, " needed daysim \t = %d \n", days_in_month(mnth)); err = 1; } else // for( ii=0; ii<daysim[mnth]; ii++ ) for( ii=0; ii<days_in_month(mnth) ; ii++ ) pvals[ii] = dc[ii]; #ifdef DBG if( tblstart[ep] <= yr && yr <= tblend[ep] && mnth == 0 ) { fprintf( fidlog, " HydroExpDist:\n"); // fprintf( fidlog, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth+1,daysim[mnth]); fprintf( fidlog, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth+1,days_in_month(mnth)); fprintf( fidlog, " started ntot \t = %d \n", ntot); fprintf( fidlog, " Generated (kk) \t = %d \n", kk); // fprintf( fidlog, " needed daysim \t = %d \n", daysim[mnth]); fprintf( fidlog, " needed daysim \t = %d \n", days_in_month(mnth)); sumx = 0.0; if( 0 ) { // for( ii=0; ii<daysim[mnth]; ii++) { for( ii=0; ii<days_in_month(mnth); ii++) { fprintf( fidlog, " ii = %d, \t pvals[ii] = %f \n", ii, pvals[ii] ); sumx += pvals[ii]; } fprintf( fidlog, " sum(pvals) \t = %f \n\n", sumx ); } } #endif return(err); } /* end of HydroExpdDist.c */
static bool clock_to_gmt(satime_t *timbuf) { int i; satime_t tmp; int year, month, day, hour, min, sec; if (machineid == HP_425 && mmuid == MMUID_425_E) { /* 425e uses mcclock on the frodo utility chip */ while ((mc_read(MC_REGA) & MC_REGA_UIP) != 0) continue; sec = mc_read(MC_SEC); min = mc_read(MC_MIN); hour = mc_read(MC_HOUR); day = mc_read(MC_DOM); month = mc_read(MC_MONTH); year = mc_read(MC_YEAR) + 1900; } else { /* Use the traditional HIL bbc for all other models */ 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; } if (year < POSIX_BASE_YEAR) year += 100; #ifdef CLOCK_DEBUG printf("clock todr: %u/%u/%u %u:%u:%u\n", year, month, day, hour, min, sec); #endif range_test(hour, 0, 23); range_test(day, 1, 31); range_test(month, 1, 12); tmp = 0; for (i = POSIX_BASE_YEAR; i < year; i++) tmp += days_per_year(i); if (is_leap_year(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 true; }
int main(void) { int heat_deg_days, /* average for coldest month */ solar_insol, /* average daily solar radiation per ft^2 for coldest month */ coldest_mon, /* coldest month: number in range 1..12 */ heating_req, /* Btu / degree day ft^2 requirement for given type of construction */ efficiency, /* % of solar insolation converted to usable heat */ collect_area, /* ft^2 needed to provide heat for coldest month */ ct, /* position in file */ status, /* file status variable */ next_hdd; /* one heating degree days value */ double floor_space, /* ft^2 */ heat_loss, /* Btu's lost in coldest month */ energy_resrc; /* Btu's heat obtained from 1 ft^2 collecting area in coldest month */ FILE *hdd_file; /* average heating degree days for each of 12 months */ FILE *solar_file; /* average solar insolation for each of 12 months */ /* Get average heating degree days for coldest month from file */ hdd_file = fopen("hdd.txt", "r"); fscanf(hdd_file, "%d", &heat_deg_days); coldest_mon = 1; ct = 2; status = fscanf(hdd_file, "%d", &next_hdd); while (status == 1) { if (next_hdd > heat_deg_days) { heat_deg_days = next_hdd; coldest_mon = ct; } ++ct; status = fscanf(hdd_file, "%d", &next_hdd); } fclose(hdd_file); /* Get corresponding average daily solar insolation from other file */ solar_file = fopen("solar.txt", "r"); solar_insol = nth_item(solar_file, coldest_mon); fclose(solar_file); /* Get from user specifics of this house */ printf("What is the approximate heating requirement (Btu / "); printf("degree day ft^2)\nof this type of construction?\n=> "); scanf("%d", &heating_req); printf("What percent of solar insolation will be converted "); printf("to usable heat?\n=> "); scanf("%d", &efficiency); printf("What is the floor space (ft^2)?\n=> "); scanf("%lf", &floor_space); /* Project collecting area needed */ heat_loss = heating_req * floor_space * heat_deg_days; energy_resrc = efficiency * 0.01 * solar_insol * days_in_month(coldest_mon); collect_area = (int)(heat_loss / energy_resrc + 0.5); /* Display results */ printf("To replace heat loss of %.0f Btu in the ", heat_loss); printf("coldest month (month %d)\nwith available ", coldest_mon); printf("solar insolation of %d Btu / ft^2 / day,", solar_insol); printf(" and an\nefficiency of %d percent,", efficiency); printf(" use a solar collecting area of %d", collect_area); printf(" ft^2.\n"); return 0; }
/* * Normalization of hours, minutes, and seconds is different than normalization of years, months, and day. * A specific time is a number of hours, minutes, and seconds that has already elapsed (e.g. 3:00 PM means * that 15 hours of the day have elapsed). A specific date is not a number of years, months, and days that * have elapsed, they indicate the current year, month, and day -- they indicate which year, month, and day * that we are in (e.g. 12/3/2009 at 8:00 AM means that 2008 years, 11 months, 2 days, 8 hours have elapsed). */ ULL operator+(const ULL& ts, const Interval& i) { // ULL t = 0; // int year,month,day,hours,minutes,seconds; // year = month = day = hours = minutes = seconds = 0; ULL t = 0; int year,month,day,hours,minutes,seconds; long inc = 0; long multiple; year = month = day = hours = minutes = seconds = 0; date_to_ymd(timestamp_date(ts), year, month, day); time_to_hms(timestamp_time(ts), hours, minutes, seconds); // add the interval's seconds, minutes, hours, and years to the values extracted from the timestamp (ts); // we'll add the months and days later seconds += i.seconds; minutes += i.minutes; hours += i.hours; year += i.years; // Since adding a number of months might affect the day, we want to normalize the months before // we go into normalizing the days. // For example: 1/29/2009 + 1 month = 1/28/2009 // but: 1/29/2008 + 1 month = 1/29/2009 // Also: 1/30/2009 + 1 month = 1/28/2009 // and: 1/31/2009 + 2 months = 3/31/2009 // ** I am assuming the the day we fall on depends on how many days the target month has in it -- If ** // ** the target month has fewer days in it than the origin month, and the origin day is a day that ** // ** the target month doesn't have, then the target day will be the last day of the target month. ** // normalize month count //int origin_month_length = days_in_month(year, month); month += i.months; // figure out how many years worth of months we can increment our year count by, // and determine which month we will be in after we remove that number of years worth of months from the month count. /* if(month > 12) { year += (month - 1) / 12; month = ((month - 1) % 12) + 1; } */ // see http://tinyurl.com/nu97yg for a demonstration of why this math works multiple = 12; inc = floor((double)(month - 1) / multiple); year += inc; month = ((month - 1) - multiple*inc) + 1; int target_month_length = days_in_month(year, month); if(/* target_month_length < origin_month_length && */ day > target_month_length) { // adjust the day of the month if we need to day = target_month_length; // set the day to the last day in the (shorter) target month } /* // normalize seconds, minutes, and hours. minutes += seconds / 60; seconds %= 60; hours += minutes / 60; minutes %= 60; // we've already normalized the month count so adding to the day count is ok here (we'll normalize the day count afterward). day += hours / 24; hours %= 24; */ // normalize seconds, minutes, and hours. multiple = 60; inc = floor((double)seconds / multiple); minutes += inc; seconds = seconds - multiple*inc; inc = floor((double)minutes / multiple); hours += inc; minutes = minutes - multiple*inc; // we've already normalized the month count so adding to the day count is ok here (we'll normalize the day count afterward). multiple = 24; inc = floor((double)hours / multiple); day += inc; hours = hours - multiple*inc; // normalize day count multiple = 12; day += i.days; int dpm = days_in_month(year, month); //cout << day << " " << dpm << endl; while(day > dpm) { day -= dpm; month++; // re-normalize month if needed inc = floor((double)(month - 1) / multiple); year += inc; month = ((month - 1) - multiple*inc) + 1; dpm = days_in_month(year, month); } while(day < 1) { month--; dpm = days_in_month(year, month); day += dpm; // re-normalize month if needed inc = floor((double)(month - 1) / multiple); year += inc; month = ((month - 1) - multiple*inc) + 1; //dpm = days_in_month(year, month); } t = join_timestamp(year, month, day, hours, minutes, seconds); return t; }
int Gregorian::days_in_month(int m) const { return days_in_month(year(), m); }
int Gregorian::days_this_month() const{ return days_in_month(month()); }