Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculate closest date/time to raw value #1

Merged
merged 1 commit into from
Aug 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions cdm/src/main/java/ucar/nc2/time/CalendarDate.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
@Immutable
public class CalendarDate implements Comparable<CalendarDate> {

public static final double MILLISECS_IN_SECOND = 1000;
public static final double MILLISECS_IN_MINUTE = MILLISECS_IN_SECOND * 60;
public static final double MILLISECS_IN_HOUR = MILLISECS_IN_MINUTE * 60;
public static final double MILLISECS_IN_DAY = MILLISECS_IN_HOUR * 24;
public static final double MILLISECS_IN_YEAR = 3.15569259747E10;
public static final double MILLISECS_IN_MONTH = MILLISECS_IN_YEAR / 12;

/**
* Get a CalendarDate representing the present moment
* @return CalendarDate representing the present moment in UTC
Expand Down Expand Up @@ -228,27 +235,22 @@ public int getHourOfDay() {
}

// old style udunits compatible.
/* day = 86400.0 seconds
week = 7 days = 604800.0 seconds
month = year/12 = 2629743.831225 seconds
year = 3.15569259747E7 seconds
*/
public CalendarDate add(double value, CalendarPeriod.Field unit) {
switch (unit) {
case Millisec:
return new CalendarDate(cal, dateTime.plus( (long) value ));
return new CalendarDate(cal, dateTime.plus( Math.round(value) ));
case Second:
return new CalendarDate(cal, dateTime.plus( (long) (value * 1000) ));
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_SECOND) ));
case Minute:
return new CalendarDate(cal, dateTime.plus( (long) (value * 60 * 1000) ));
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_MINUTE) ));
case Hour:
return new CalendarDate(cal, dateTime.plus( (long) (value * 60 * 60 * 1000) ));
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_HOUR) ));
case Day:
return new CalendarDate(cal, dateTime.plus( (long) (value * 86400 * 1000) ));
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_DAY) ));
case Month: // LOOK should we throw warning ?
return new CalendarDate(cal, dateTime.plus( (long) (value * 2629743.831225 * 1000) ));
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_MONTH) ));
case Year: // LOOK should we throw warning ?
return new CalendarDate(cal, dateTime.plus( (long) (value * 3.15569259747E10) )); // millisecs!
return new CalendarDate(cal, dateTime.plus( Math.round(value * MILLISECS_IN_YEAR) ));
}
throw new UnsupportedOperationException("period units = "+unit);
}
Expand Down
25 changes: 25 additions & 0 deletions cdm/src/test/java/ucar/nc2/time/TestCalendarDate.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package ucar.nc2.time;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import ucar.nc2.time.CalendarPeriod.Field;

/**
* CalendarDate testing
*
Expand Down Expand Up @@ -36,4 +40,25 @@ public void testDateTimeFields() {
cd = CalendarDate.of(null, 1,1,1,1,1,0);
}

@Test
public void testAddReturnsClosestDate() {
String baseDate = "1950-01-01";
double valueInMillisecs = 2025829799999.99977;
String expectedResult = "2014-03-13T02:30:00Z";

assertAddReturnsExpectedDate(baseDate, valueInMillisecs, Field.Millisec, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_SECOND, Field.Second, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_MINUTE, Field.Minute, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_HOUR, Field.Hour, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_DAY, Field.Day, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_MONTH, Field.Month, expectedResult);
assertAddReturnsExpectedDate(baseDate, valueInMillisecs/CalendarDate.MILLISECS_IN_YEAR, Field.Year, expectedResult);
}

private void assertAddReturnsExpectedDate(String baseDate, double value, Field units, String expectedResult) {
CalendarDate base = CalendarDateFormatter.isoStringToCalendarDate(Calendar.gregorian, baseDate);
CalendarDate result = base.add(value, units);
assertEquals(units.toString(), expectedResult, CalendarDateFormatter.toDateTimeStringISO(result));
}

}