예제 #1
0
파일: datetime.c 프로젝트: rdebath/sgt
Date parse_date(char *str)
{
    int y, m, d, y2, m2, d2, delta;
    Date ret;

    if (sscanf(str, "%d-%d-%d", &y, &m, &d) == 3) {
	if (d < 1 || d > 31 || m < 1 || m > 12 || y < 1900)
	    return INVALID_DATE;

	ret = ymd_to_date(y, m, d);

	/*
	 * Double-check the user hasn't entered anything stupid such as
	 * 30th Feb.
	 */
	date_to_ymd(ret, &y2, &m2, &d2);
	if (y2 != y || m2 != m || d2 != d)
	    return INVALID_DATE;
    } else if (sscanf(str, "+%d", &delta) == 1) {
	return today() + delta;
    } else if (sscanf(str, "-%d", &delta) == 1) {
	return today() - delta;
    } else {
	return INVALID_DATE;
    }

    return ret;
}
예제 #2
0
파일: datetime.c 프로젝트: rdebath/sgt
char *format_date_core(Date d, int full)
{
    char *s, *t;
    int yy, mm, dd;

    date_to_ymd(d, &yy, &mm, &dd); 

    s = smalloc(32);

    if (d == INVALID_DATE)
	sprintf(s, full ? "*INVALID DATE*" : "*INVALID!*");
    else if (d == NO_DATE)
	sprintf(s, "%*s", full ? 14 : 10, "");
    else {
	if (full) {
	    t = s + sprintf(s, "%3s ", weekdays[weekday(d)]);
	} else
	    t = s;
	sprintf(t, "%4d-%02d-%02d", yy, mm, dd);
    }

    return s;
}
예제 #3
0
파일: datetime.c 프로젝트: rdebath/sgt
int main(void)
{
    Date sd, ed, d;
    struct { int y, m, d, ymd; } curr, prev;

    sd = ymd_to_date(1995, 1, 1);
    ed = ymd_to_date(2005, 1, 1);
    assert(ed - sd > 365 * 8);

    for (d = sd; d <= ed; d++) {
	date_to_ymd(d, &curr.y, &curr.m, &curr.d);
	curr.ymd = 10000 * curr.y + 100 * curr.m + curr.d;

	if (d == sd) {
	    prev = curr;
	    continue;
	}

	printf("prev: %4d-%02d-%02d  curr: %4d-%02d-%02d  d:%8d\n",
	       prev.y, prev.m, prev.d, curr.y, curr.m, curr.d, d);

	/* Monotonicity. */
	assert(prev.ymd < curr.ymd);

	/* Other obvious date properties. */
	if (curr.d != 1) {
	    /* Date increases by 1 except at start of new month. */
	    assert(prev.y == curr.y);
	    assert(prev.m == curr.m);
	    assert(prev.d == curr.d - 1);
	} else if (curr.m != 1) {
	    /* Month increases by 1 except at start of new year. */
	    assert(prev.y == curr.y);
	    assert(prev.m == curr.m - 1);

	    switch (prev.m) {
	      case 9: case 4: case 6: case 11:
		/* 30 days hath September, April, June and November ... */
		assert(prev.d == 30);
		break;
	      default:
		/* All the rest have 31 ... */
		assert(prev.d == 31);
		break;
	      case 2:
		/* except for February. */
		if (prev.y % 4)
		    assert(prev.d == 28);
		else
		    assert(prev.d == 29);
		break;
	    }
	} else {
	    /* Year increases by 1. */
	    assert(prev.y == curr.y - 1);
	}

	/* Round-trip conversion. */
	assert(ymd_to_date(curr.y, curr.m, curr.d) == d);

	/* And round to the next one. */
	prev = curr;
    }

    printf("tests passed ok\n");
    return 0;
}
예제 #4
0
void test_date_time_implementation() {
  ULL timestamp = 20090618001732ULL;
  int dt;
  int tm;
  int Y,M,D,h,m,s;

  split_timestamp(timestamp, dt, tm);
  date_to_ymd(dt, Y, M, D);
  time_to_hms(tm, h, m, s);

  cout << "Timestamp: " << timestamp << endl;
  cout << "Date: " << dt << " -> " << Y << "/" << M << "/" << D << endl;
  cout << "Time: " << tm << " -> " << h << ":" << m << ":" << s << endl << endl;

  UL seconds = 31834133;
  Interval i = Interval(0,0,0,0,0,seconds);
  cout << "20080101 + 31834133 seconds  = " << join_timestamp(20080101, 0) + i << endl;
  cout << "20080101 - -31834133 seconds = " << join_timestamp(20080101, 0) - -i << endl;
  cout << "20080101 - 31834133 seconds  = " << join_timestamp(20080101, 0) - i << endl;
  cout << "20080101 + -31834133 seconds = " << join_timestamp(20080101, 0) + -i << endl;

  cout << endl;
  
  i = Interval(1, 3, 3, 25, 7, 38);
  cout << "20090601 + (1 year 3 months 3 days 25 hours 7 minutes 38 seconds)  = " << join_timestamp(20090601, 0) + i << endl;
  cout << "20090601 - -(1 year 3 months 3 days 25 hours 7 minutes 38 seconds) = " << join_timestamp(20090601, 0) - (-i) << endl;
  cout << "20090601 - (1 year 3 months 3 days 25 hours 7 minutes 38 seconds)  = " << join_timestamp(20090601, 0) - i << endl;
  cout << "20090601 + -(1 year 3 months 3 days 25 hours 7 minutes 38 seconds) = " << join_timestamp(20090601, 0) + (-i) << endl;

  cout << endl;
  
  Interval l = Interval(2, 3, 32, 25, 7, 112);
  Interval r = Interval(1, 15, 33, 1, 8, 52);
  cout << "(2 years 3 months 32 days 25 hours 7 minutes 112 seconds) <=> (1 year 15 months 33 days 1 hour 8 minutes 52 seconds) = " << leg(l,r) << endl;

  cout << endl;
  
  l = Interval(0,0,0,0,0,31834133);
  r = Interval(0, 0, 368, 10, 48, 52);
  cout << "(31834133 seconds) <=> (368 days 10 hours 48 minutes 52 seconds) = " << leg(l,r) << endl;
  cout << "(31834133 seconds) > (368 days 10 hours 48 minutes 52 seconds) = " << ((l > r) ? "true" : "false") << endl;
  r = Interval(0, 0, 368, 10, 48, 53);
  cout << "(31834133 seconds) <=> (368 days 10 hours 48 minutes 53 seconds) = " << leg(l,r) << endl;
  cout << "(31834133 seconds) == (368 days 10 hours 48 minutes 53 seconds) = " << ((l == r) ? "true" : "false") << endl;
  r = Interval(0, 0, 368, 10, 48, 54);
  cout << "(31834133 seconds) <=> (368 days 10 hours 48 minutes 54 seconds) = " << leg(l,r) << endl;
  cout << "(31834133 seconds) < (368 days 10 hours 48 minutes 54 seconds) = " << ((l < r) ? "true" : "false") << endl;
  
  cout << endl;
  
  ULL t1 = 19831129031500ULL;       // my birth date (time?)
  ULL t2 = 20090626005206ULL;       // now
  i = Interval::between(t1, t2);
  l = Interval(25, 6, 27, 21, 37, 6);
  r = Interval(0, 0, 9340, 21, 37, 6);
  cout << "Interval between 1983-11-29 03:15:00 and 2009-06-26 00:52:06 = " << i.to_s() << endl;
  cout << i.to_s() << " <=> " << l.to_s() << " = " << leg(i, l) << endl;
  cout << i.to_s() << " <=> " << r.to_s() << " = " << leg(i, r) << endl;
  cout << l.to_s() << " <=> " << r.to_s() << " = " << leg(l, r) << endl;
  
  cout << endl;
  
  l = Interval(0, 1, -29, 4, -29, 0);
  r = Interval(0, 0, 2, 3, 31, 0);
  cout << l.to_s() << " <=> " << r.to_s() << " = " << leg(l, r) << endl;
  cout << l.to_s() << " < " << r.to_s() << "  -> " << ((l < r) ? "true" : "false") << endl;
  cout << l.to_s() << " == " << r.to_s() << " -> " << ((l == r) ? "true" : "false") << endl;
  cout << l.to_s() << " > " << r.to_s() << "  -> " << ((l > r) ? "true" : "false") << endl;
  
  cout << endl;
  
  i = Interval(390, -1354, -3395, -6671, -5719, 0);       // ~9.7556 days
  long divisor = 10000;
  cout << i.to_s() << " / " << divisor << " = " << (i / divisor).to_s() << endl;
  
  cout << endl;
  
  cout << "Day of week of 20090623 is a " << getDayOfWeek(6, 23, 2009, 1);
}
예제 #5
0
int getDayOfWeek(ULL timestamp, int CalendarSystem) {
  int year, month, day;
  year = month = day = 0;
  date_to_ymd(timestamp_date(timestamp), year, month, day);
  return getDayOfWeek(month, day, year, CalendarSystem);
}
예제 #6
0
void split_timestamp(ULL timestamp, int& out_year, int& out_month, int& out_day, int& out_hour, int& out_minute, int& out_second) {
  date_to_ymd(timestamp_date(timestamp), out_year, out_month, out_day);
  time_to_hms(timestamp_time(timestamp), out_hour, out_minute, out_second);
}
예제 #7
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;
}