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

ISO Support for Time Grains #1739

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

Expand All @@ -26,22 +25,23 @@ public Day(java.util.Date date) {
}

@ElideTypeConverter(type = Day.class, name = "Day")
static public class DaySerde implements Serde<Object, Day> {
static public class DaySerde implements Serde<Object, Day>, TimeGrainFormatter {
@Override
public Day deserialize(Object val) {

Day date = null;

try {
if (val instanceof String) {
date = new Day(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Day(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Day(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ public Hour(java.util.Date date) {
}

@ElideTypeConverter(type = Hour.class, name = "Hour")
static public class HourSerde implements Serde<Object, Hour> {
static public class HourSerde implements Serde<Object, Hour>, TimeGrainFormatter {
@Override
public Hour deserialize(Object val) {

Hour date = null;

try {
if (val instanceof String) {
date = new Hour(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Hour(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Hour(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

Expand All @@ -26,7 +25,7 @@ public ISOWeek(java.util.Date date) {
}

@ElideTypeConverter(type = ISOWeek.class, name = "ISOWeek")
static public class ISOWeekSerde implements Serde<Object, ISOWeek> {
static public class ISOWeekSerde implements Serde<Object, ISOWeek>, TimeGrainFormatter {
private static final SimpleDateFormat WEEKDATE_FORMATTER = new SimpleDateFormat("u");

@Override
Expand All @@ -36,12 +35,14 @@ public ISOWeek deserialize(Object val) {

try {
if (val instanceof String) {
date = new ISOWeek(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new ISOWeek(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new ISOWeek(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

if (!WEEKDATE_FORMATTER.format(date).equals("1")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ public Minute(java.util.Date date) {
}

@ElideTypeConverter(type = Minute.class, name = "Minute")
static public class MinuteSerde implements Serde<Object, Minute> {
static public class MinuteSerde implements Serde<Object, Minute>, TimeGrainFormatter {
@Override
public Minute deserialize(Object val) {

Minute date = null;

try {
if (val instanceof String) {
date = new Minute(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Minute(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look correct - why do we need to parse and then format, and then parse again? It looks like we are doing unnecessary work here.

(String) val))));
} else {
date = new Minute(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

Expand All @@ -26,20 +25,22 @@ public Month(java.util.Date date) {
}

@ElideTypeConverter(type = Month.class, name = "Month")
static public class MonthSerde implements Serde<Object, Month> {
static public class MonthSerde implements Serde<Object, Month>, TimeGrainFormatter {
@Override
public Month deserialize(Object val) {

Month date = null;

try {
if (val instanceof String) {
date = new Month(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Month(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Month(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
Expand All @@ -29,7 +28,7 @@ public Quarter(java.util.Date date) {
}

@ElideTypeConverter(type = Quarter.class, name = "Quarter")
static public class QuarterSerde implements Serde<Object, Quarter> {
static public class QuarterSerde implements Serde<Object, Quarter>, TimeGrainFormatter {
private static final SimpleDateFormat MONTH_FORMATTER = new SimpleDateFormat("M");
private static final Set<String> QUARTER_MONTHS = new HashSet<>(Arrays.asList("1", "4", "7", "10"));

Expand All @@ -40,12 +39,14 @@ public Quarter deserialize(Object val) {

try {
if (val instanceof String) {
date = new Quarter(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Quarter(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Quarter(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

if (!QUARTER_MONTHS.contains(MONTH_FORMATTER.format(date))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,22 @@ public String toString() {
}

@ElideTypeConverter(type = Second.class, name = "Second")
static public class SecondSerde implements Serde<Object, Second> {
static public class SecondSerde implements Serde<Object, Second>, TimeGrainFormatter {
@Override
public Second deserialize(Object val) {

Second date = null;

try {
if (val instanceof String) {
date = new Second(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Second(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Second(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2020, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.timegrains;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/** Interface for ISO timegrain Support. */
public interface TimeGrainFormatter {

String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
SimpleDateFormat ISO_FORMATTER = new SimpleDateFormat(ISO_FORMAT);

static Timestamp formatDateString(SimpleDateFormat formatter, String val) throws ParseException {
try {
return new Timestamp(formatter.parse((String) val).getTime());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to cast val here as a String.

} catch (ParseException pe) {
return new Timestamp(ISO_FORMATTER.parse((String) val).getTime());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

Expand All @@ -26,7 +25,7 @@ public Week(java.util.Date date) {
}

@ElideTypeConverter(type = Week.class, name = "Week")
static public class WeekSerde implements Serde<Object, Week> {
static public class WeekSerde implements Serde<Object, Week>, TimeGrainFormatter {
private static final SimpleDateFormat WEEKDATE_FORMATTER = new SimpleDateFormat("u");

@Override
Expand All @@ -36,12 +35,14 @@ public Week deserialize(Object val) {

try {
if (val instanceof String) {
date = new Week(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Week(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Week(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

if (!WEEKDATE_FORMATTER.format(date).equals("7")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.yahoo.elide.core.utils.coerce.converters.Serde;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

Expand All @@ -34,12 +33,14 @@ public Year deserialize(Object val) {

try {
if (val instanceof String) {
date = new Year(new Timestamp(FORMATTER.parse((String) val).getTime()));
date = new Year(FORMATTER.parse(FORMATTER.format(TimeGrainFormatter.formatDateString(FORMATTER,
(String) val))));
} else {
date = new Year(FORMATTER.parse(FORMATTER.format(val)));
}
} catch (ParseException e) {
throw new IllegalArgumentException("String must be formatted as " + FORMAT);
throw new IllegalArgumentException("String must be formatted as " + FORMAT
+ " or " + TimeGrainFormatter.ISO_FORMAT);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.yahoo.elide.core.utils.coerce.converters.Serde;
import com.yahoo.elide.datastores.aggregation.timegrains.Day;
import org.junit.jupiter.api.Test;
Expand All @@ -17,6 +18,7 @@

public class DaySerdeTest {
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
private SimpleDateFormat isoFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

@Test
public void testDateSerialize() throws ParseException {
Expand Down Expand Up @@ -59,4 +61,14 @@ public void testDeserializeDateInvalidFormat() throws ParseException {
serde.deserialize(dateInString);
});
}

@Test
public void testISODateString() throws ParseException {
String dateInString = "2020-01-01T00:00:00-0500";
Day expectedDate = new Day(formatter.parse(dateInString));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be isoFormatter instead of formatter. Also might be a good idea to update dateInString to have different hour minutes.

String actual = "2020-01-01";
Serde serde = new Day.DaySerde();
Object actualDate = serde.deserialize(actual);
assertEquals(expectedDate, actualDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

public class HourSerdeTest {
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH");
private SimpleDateFormat isoFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

@Test
public void testDateSerialize() throws ParseException {
Expand Down Expand Up @@ -60,4 +61,14 @@ public void testDeserializeDateInvalidFormat() throws ParseException {
serde.deserialize(dateInString);
});
}

@Test
public void testISODateString() throws ParseException {
String dateInString = "2021-01-12T08:00:00-0500";
String expectedDate = new Hour(isoFormatter.parse(dateInString)).toString();
Timestamp timestamp = new Timestamp(isoFormatter.parse(dateInString).getTime());
Serde serde = new Hour.HourSerde();
String actualDate = serde.deserialize(timestamp).toString();
assertEquals(expectedDate, actualDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

public class ISOWeekSerdeTest {
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
private SimpleDateFormat isoFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

@Test
public void testDateSerialize() throws ParseException {
Expand Down Expand Up @@ -71,4 +72,14 @@ public void testDeserializeDateInvalidFormat() throws ParseException {
serde.deserialize(dateInString);
});
}

@Test
public void testISODateString() throws ParseException {
String dateInString = "2020-01-06T00:00:00-0500";
Date expectedDate = new Date(formatter.parse(dateInString).getTime());
String actual = "2020-01-06";
Serde serde = new ISOWeek.ISOWeekSerde();
Object actualDate = serde.deserialize(actual);
assertEquals(expectedDate, actualDate);
}
}