Skip to content

Commit

Permalink
Accessors: epochSeconds, offsetMinutes
Browse files Browse the repository at this point in the history
Also support epochSeconds during creation. Rename epoch to epochMillis.
  • Loading branch information
sherfert committed Mar 16, 2018
1 parent 5141e7e commit 1df1fcd
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 31 deletions.
Expand Up @@ -220,7 +220,7 @@ public DateTimeValue buildInternal()
boolean selectingDate = fields.containsKey( Field.date ); boolean selectingDate = fields.containsKey( Field.date );
boolean selectingTime = fields.containsKey( Field.time ); boolean selectingTime = fields.containsKey( Field.time );
boolean selectingDateTime = fields.containsKey( Field.datetime ); boolean selectingDateTime = fields.containsKey( Field.datetime );
boolean selectingEpoch = fields.containsKey( Field.epoch ); boolean selectingEpoch = fields.containsKey( Field.epochSeconds ) || fields.containsKey( Field.epochMillis );
boolean selectingTimeZone; boolean selectingTimeZone;
ZonedDateTime result; ZonedDateTime result;
if ( selectingDateTime ) if ( selectingDateTime )
Expand All @@ -238,13 +238,26 @@ public DateTimeValue buildInternal()
} }
else if ( selectingEpoch ) else if ( selectingEpoch )
{ {
AnyValue epochField = fields.get( Field.epoch ); if( fields.containsKey( Field.epochSeconds ) )
if ( !(epochField instanceof IntegralValue) )
{ {
throw new IllegalArgumentException( String.format( "Cannot construct date time from: %s", epochField ) ); AnyValue epochField = fields.get( Field.epochSeconds );
if ( !(epochField instanceof IntegralValue) )
{
throw new IllegalArgumentException( String.format( "Cannot construct date time from: %s", epochField ) );
}
IntegralValue epochSeconds = (IntegralValue) epochField;
result = ZonedDateTime.ofInstant( Instant.ofEpochMilli( epochSeconds.longValue() * 1000 ), timezone() );
}
else
{
AnyValue epochField = fields.get( Field.epochMillis );
if ( !(epochField instanceof IntegralValue) )
{
throw new IllegalArgumentException( String.format( "Cannot construct date time from: %s", epochField ) );
}
IntegralValue epochMillis = (IntegralValue) epochField;
result = ZonedDateTime.ofInstant( Instant.ofEpochMilli( epochMillis.longValue() ), timezone() );
} }
IntegralValue epoch = (IntegralValue) epochField;
result = ZonedDateTime.ofInstant( Instant.ofEpochMilli( epoch.longValue() ), timezone() );
selectingTimeZone = false; selectingTimeZone = false;
} }
else if ( selectingTime || selectingDate ) else if ( selectingTime || selectingDate )
Expand Down
Expand Up @@ -270,13 +270,20 @@ public final int get( TemporalField field )
public final AnyValue get( String fieldName ) public final AnyValue get( String fieldName )
{ {
Field field = Field.fields.get( fieldName.toLowerCase() ); Field field = Field.fields.get( fieldName.toLowerCase() );
if ( field == Field.epoch ) if ( field == Field.epochSeconds || field == Field.epochMillis )
{ {
T temp = temporal(); T temp = temporal();
if ( temp instanceof ChronoZonedDateTime ) if ( temp instanceof ChronoZonedDateTime )
{ {
ChronoZonedDateTime zdt = (ChronoZonedDateTime) temp; ChronoZonedDateTime zdt = (ChronoZonedDateTime) temp;
return Values.longValue( zdt.toInstant().toEpochMilli() ); if ( field == Field.epochSeconds )
{
return Values.longValue( zdt.toInstant().toEpochMilli() / 1000 );
}
else
{
return Values.longValue( zdt.toInstant().toEpochMilli() );
}
} }
else else
{ {
Expand All @@ -291,6 +298,10 @@ public final AnyValue get( String fieldName )
{ {
return Values.stringValue( getZoneOffset().toString() ); return Values.stringValue( getZoneOffset().toString() );
} }
if ( field == Field.offsetMinutes )
{
return Values.intValue( getZoneOffset().getTotalSeconds() / 60 );
}
if ( field == null || field.field == null ) if ( field == null || field.field == null )
{ {
throw new UnsupportedTemporalTypeException( "No such field: " + fieldName ); throw new UnsupportedTemporalTypeException( "No such field: " + fieldName );
Expand Down Expand Up @@ -564,6 +575,15 @@ void assign( Builder<?> builder, AnyValue value )
throw new IllegalArgumentException( "Not supported: " + name() ); throw new IllegalArgumentException( "Not supported: " + name() );
} }
}, },
offsetMinutes//<pre>
{ //</pre>

@Override
void assign( Builder<?> builder, AnyValue value )
{
throw new IllegalArgumentException( "Not supported: " + name() );
}
},
// time zone // time zone
timezone//<pre> timezone//<pre>
{ //</pre> { //</pre>
Expand Down Expand Up @@ -652,7 +672,30 @@ boolean isGroupSelector()
return true; return true;
} }
}, },
epoch//<pre> epochSeconds//<pre>
{ //<pre>

@Override
void assign( Builder<?> builder, AnyValue value )
{
if ( !builder.supportsEpoch() )
{
throw new IllegalArgumentException( "Not supported: " + name() );
}
if ( builder.state == null )
{
builder.state = new DateTimeBuilder( );
}
builder.state = builder.state.assign( this, value );
}

@Override
boolean isGroupSelector()
{
return true;
}
},
epochMillis//<pre>
{ //<pre> { //<pre>


@Override @Override
Expand Down Expand Up @@ -763,7 +806,7 @@ void checkAssignments( boolean requiresDate )


DateTimeBuilder assign( Field field, AnyValue value ) DateTimeBuilder assign( Field field, AnyValue value )
{ {
if ( field == Field.datetime || field == Field.epoch ) if ( field == Field.datetime || field == Field.epochSeconds || field == Field.epochMillis )
{ {
return new SelectDateTimeDTBuilder( date, time ).assign( field, value ); return new SelectDateTimeDTBuilder( date, time ).assign( field, value );
} }
Expand Down Expand Up @@ -806,7 +849,8 @@ else if ( field == Field.time || field.field != null && field.field.isTimeBased(
private static class SelectDateTimeDTBuilder extends DateTimeBuilder private static class SelectDateTimeDTBuilder extends DateTimeBuilder
{ {
private AnyValue datetime; private AnyValue datetime;
private AnyValue epoch; private AnyValue epochSeconds;
private AnyValue epochMillis;


SelectDateTimeDTBuilder( DateBuilder date, ConstructTime time ) SelectDateTimeDTBuilder( DateBuilder date, ConstructTime time )
{ {
Expand All @@ -824,23 +868,43 @@ DateTimeBuilder assign( Field field, AnyValue value )
{ {
if ( field == Field.date || field == Field.time ) if ( field == Field.date || field == Field.time )
{ {
throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime or epoch." ); throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime or epochSeconds or epochMillis." );
} }
else if ( field == Field.datetime ) else if ( field == Field.datetime )
{ {
if ( epoch != null ) if ( epochSeconds != null )
{ {
throw new IllegalArgumentException( field.name() + " cannot be selected together with epoch." ); throw new IllegalArgumentException( field.name() + " cannot be selected together with epochSeconds." );
}
else if ( epochMillis != null )
{
throw new IllegalArgumentException( field.name() + " cannot be selected together with epochMillis." );
} }
datetime = assignment( Field.datetime, datetime, value ); datetime = assignment( Field.datetime, datetime, value );
} }
else if ( field == Field.epoch ) else if ( field == Field.epochSeconds )
{ {
if ( datetime != null ) if ( epochMillis != null )
{
throw new IllegalArgumentException( field.name() + " cannot be selected together with epochMillis." );
}
else if ( datetime != null )
{
throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime." );
}
epochSeconds = assignment( Field.epochSeconds, epochSeconds, value );
}
else if ( field == Field.epochMillis )
{
if ( epochSeconds != null )
{
throw new IllegalArgumentException( field.name() + " cannot be selected together with epochSeconds." );
}
else if ( datetime != null )
{ {
throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime." ); throw new IllegalArgumentException( field.name() + " cannot be selected together with datetime." );
} }
epoch = assignment( Field.epoch, epoch, value ); epochMillis = assignment( Field.epochMillis, epochMillis, value );
} }
else else
{ {
Expand All @@ -860,7 +924,7 @@ private static class SelectDateOrTimeDTBuilder extends DateTimeBuilder
@Override @Override
DateTimeBuilder assign( Field field, AnyValue value ) DateTimeBuilder assign( Field field, AnyValue value )
{ {
if ( field == Field.datetime || field == Field.epoch ) if ( field == Field.datetime || field == Field.epochSeconds || field == Field.epochMillis )
{ {
throw new IllegalArgumentException( field.name() + " cannot be selected together with date or time." ); throw new IllegalArgumentException( field.name() + " cannot be selected together with date or time." );
} }
Expand Down
Expand Up @@ -61,11 +61,11 @@ Feature: TemporalAccessorAcceptance
When executing query: When executing query:
""" """
WITH time({hour:12, minute:31, second:14, nanosecond: 645876123, timezone:'+01:00'}) as d WITH time({hour:12, minute:31, second:14, nanosecond: 645876123, timezone:'+01:00'}) as d
RETURN d.hour, d.minute, d.second, d.millisecond, d.microsecond, d.nanosecond, d.timezone, d.offset RETURN d.hour, d.minute, d.second, d.millisecond, d.microsecond, d.nanosecond, d.timezone, d.offset, d.offsetMinutes
""" """
Then the result should be, in order: Then the result should be, in order:
| d.hour | d.minute | d.second | d.millisecond | d.microsecond | d.nanosecond | d.timezone | d.offset | | d.hour | d.minute | d.second | d.millisecond | d.microsecond | d.nanosecond | d.timezone | d.offset | d.offsetMinutes |
| 12 | 31 | 14 | 645 | 645876 | 645876123 | '+01:00' | '+01:00' | | 12 | 31 | 14 | 645 | 645876 | 645876123 | '+01:00' | '+01:00' | 60 |
And no side effects And no side effects


Scenario: Should provide accessors for local date time Scenario: Should provide accessors for local date time
Expand All @@ -88,11 +88,11 @@ Feature: TemporalAccessorAcceptance
WITH datetime({year:1984, month:11, day:11, hour:12, minute:31, second:14, nanosecond: 645876123, timezone:'Europe/Stockholm'}) as d WITH datetime({year:1984, month:11, day:11, hour:12, minute:31, second:14, nanosecond: 645876123, timezone:'Europe/Stockholm'}) as d
RETURN d.year, d.quarter, d.month, d.week, d.weekYear, d.day, d.ordinalDay, d.weekDay, d.dayOfQuarter, RETURN d.year, d.quarter, d.month, d.week, d.weekYear, d.day, d.ordinalDay, d.weekDay, d.dayOfQuarter,
d.hour, d.minute, d.second, d.millisecond, d.microsecond, d.nanosecond, d.hour, d.minute, d.second, d.millisecond, d.microsecond, d.nanosecond,
d.timezone, d.offset, d.epoch d.timezone, d.offset, d.offsetMinutes, d.epochSeconds, d.epochMillis
""" """
Then the result should be, in order: Then the result should be, in order:
| d.year | d.quarter | d.month | d.week | d.weekYear | d.day | d.ordinalDay | d.weekDay | d.dayOfQuarter | d.hour | d.minute | d.second | d.millisecond | d.microsecond | d.nanosecond | d.timezone | d.offset | d.epoch | | d.year | d.quarter | d.month | d.week | d.weekYear | d.day | d.ordinalDay | d.weekDay | d.dayOfQuarter | d.hour | d.minute | d.second | d.millisecond | d.microsecond | d.nanosecond | d.timezone | d.offset | d.offsetMinutes | d.epochSeconds | d.epochMillis |
| 1984 | 4 | 11 | 45 | 1984 | 11 | 316 | 7 | 42 | 12 | 31 | 14 | 645 | 645876 | 645876123 | 'Europe/Stockholm' | '+01:00' | 469020674645 | | 1984 | 4 | 11 | 45 | 1984 | 11 | 316 | 7 | 42 | 12 | 31 | 14 | 645 | 645876 | 645876123 | 'Europe/Stockholm' | '+01:00' | 60 | 469020674 | 469020674645 |
And no side effects And no side effects


Scenario: Should provide accessors for duration Scenario: Should provide accessors for duration
Expand Down
Expand Up @@ -41,7 +41,8 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic
shouldReturnSomething(s"$s.realtime('America/Los_Angeles')") shouldReturnSomething(s"$s.realtime('America/Los_Angeles')")
shouldReturnSomething(s"$s({timezone: '+01:00'})") shouldReturnSomething(s"$s({timezone: '+01:00'})")
} }
shouldReturnSomething("datetime({epoch:timestamp()})") shouldReturnSomething("datetime({epochMillis:timestamp()})")
shouldReturnSomething("datetime({epochSeconds:timestamp() / 1000})")
} }


// Failing when skipping certain values in create or specifying conflicting values // Failing when skipping certain values in create or specifying conflicting values
Expand Down Expand Up @@ -115,8 +116,9 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic
"{year:1984, month: 2, quarter:11}", "{year:1984, month: 2, dayOfQuarter:11}", "{year:1984, month: 2, quarter:11}", "{year:1984, month: 2, dayOfQuarter:11}",
"{year:1984, week: 2, day:11}", "{year:1984, week: 2, quarter:11}", "{year:1984, week: 2, dayOfQuarter:11}", "{year:1984, week: 2, day:11}", "{year:1984, week: 2, quarter:11}", "{year:1984, week: 2, dayOfQuarter:11}",
"{year:1984, quarter: 2, day:11}", "{year:1984, quarter: 2, dayOfWeek:6}", "{datetime: datetime(), date: date()}", "{year:1984, quarter: 2, day:11}", "{year:1984, quarter: 2, dayOfWeek:6}", "{datetime: datetime(), date: date()}",
"{datetime: datetime(), time: time()}", "{datetime: datetime(), epoch: timestamp()}", "{date: date(), epoch: timestamp()}", "{datetime: datetime(), time: time()}", "{datetime: datetime(), epochSeconds:1}", "{datetime: datetime(), epochMillis: timestamp()}",
"{time: time(), epoch: timestamp()}") "{date: date(), epochSeconds:1}","{date: date(), epochMillis: timestamp()}",
"{time: time(), epochSeconds:1}", "{time: time(), epochMillis: timestamp()}", "{epochSeconds:1, epochMillis: timestamp()}")
shouldNotConstructWithArg("datetime", queries) shouldNotConstructWithArg("datetime", queries)
} }


Expand Down Expand Up @@ -450,13 +452,13 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic


test("should not provide undefined accessors for date") { test("should not provide undefined accessors for date") {
shouldNotHaveAccessor("date", Seq("hour", "minute", "second", "millisecond", "microsecond", "nanosecond", shouldNotHaveAccessor("date", Seq("hour", "minute", "second", "millisecond", "microsecond", "nanosecond",
"timezone", "offset", "epoch", "timezone", "offset", "offsetMinutes", "epochSeconds", "epochMillis",
"years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds")) "years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds"))
} }


test("should not provide undefined accessors for local time") { test("should not provide undefined accessors for local time") {
shouldNotHaveAccessor("localtime", Seq("year", "quarter", "month", "week", "weekYear", "day", "ordinalDay", "weekDay", "dayOfQuarter", shouldNotHaveAccessor("localtime", Seq("year", "quarter", "month", "week", "weekYear", "day", "ordinalDay", "weekDay", "dayOfQuarter",
"timezone", "offset", "epoch", "timezone", "offset", "offsetMinutes", "epochSeconds", "epochMillis",
"years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds")) "years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds"))
} }


Expand All @@ -466,7 +468,7 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic
} }


test("should not provide undefined accessors for local date time") { test("should not provide undefined accessors for local date time") {
shouldNotHaveAccessor("localdatetime", Seq("timezone", "offset", "epoch", shouldNotHaveAccessor("localdatetime", Seq("timezone", "offset", "offsetMinutes", "epochSeconds", "epochMillis",
"years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds")) "years", "months", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds"))
} }


Expand All @@ -477,7 +479,7 @@ class TemporalAcceptanceTest extends ExecutionEngineFunSuite with QueryStatistic
test("should not provide undefined accessors for duration") { test("should not provide undefined accessors for duration") {
shouldNotHaveAccessor("duration", Seq("year", "quarter", "month", "week", "weekYear", "day", "ordinalDay", "weekDay", "dayOfQuarter", shouldNotHaveAccessor("duration", Seq("year", "quarter", "month", "week", "weekYear", "day", "ordinalDay", "weekDay", "dayOfQuarter",
"hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond",
"timezone", "offset", "epoch"), "{days: 14, hours:16, minutes: 12}") "timezone", "offset", "offsetMinutes", "epochSeconds", "epochMillis"), "{days: 14, hours:16, minutes: 12}")
} }


// Duration between // Duration between
Expand Down

0 comments on commit 1df1fcd

Please sign in to comment.