/*************************************************************************** * Copyright (C) 2012 by H-Store Project * * Brown University * * Massachusetts Institute of Technology * * Yale University * * * * Alex Kalinin (akalinin@cs.brown.edu) * * http://www.cs.brown.edu/~akalinin/ * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * ***************************************************************************/ package edu.brown.benchmark.tpce.util; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; import org.voltdb.types.*; import edu.brown.benchmark.tpce.TPCEConstants; public class EGenDate { /* * The idea here is to set up a pure Gregorian calendar without a time zone offset * to use it for generating day numbers properly. This will correspond with the * canonical EGen implementation. * * However, it should be noted that since the TIMESTAMP is used for the corresponding SQL data type, * the interpretation of the generated value depends on current time zone and daylight saving settings since * the generated value is just a number of milliseconds from the Epoch. * * For example, the generated '1990-12-13' will be interpreted as '1990-12-12, 19:00' in EDT (daylight saving) * the generated '1953-09-26' will be interpreted as '1953-09-25, 20:00' in EDT (no daylight saving) */ public static final GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); // no time zone private static final int cur_year; private static final int cur_month; private static final int cur_day; private static int cur_hour; private static int cur_minute; private static int cur_second; private static int cur_msecond; public static final double NsPerSecondDivisor = 1000000000.0; public static final int NsPerSecond = 1000000000; public static final double MsPerSecondDivisor = 1000.000; public static final int MsPerSecond = 1000; public static final int SecondsPerMinute = 60; public static final int MinutesPerHour = 60; public static final int HoursPerDay = 24; public static final int HoursPerWorkDay = 8; public static final int DaysPerWorkWeek = 5; public static final int DaysPerWeek = 7; public static final int SecondsPerHour = SecondsPerMinute * MinutesPerHour; public static final int SecondsPerDay = SecondsPerMinute * MinutesPerHour * HoursPerDay; public static final int SecondsPerWorkDay = SecondsPerMinute * MinutesPerHour * HoursPerWorkDay; public static final int MsPerDay = SecondsPerDay * MsPerSecond; public static final int MsPerWorkDay = SecondsPerWorkDay * MsPerSecond; static { cal.setGregorianChange(new Date(Long.MIN_VALUE)); // pure Gregorian calendar cur_year = cal.get(Calendar.YEAR); cur_month = cal.get(Calendar.MONTH); cur_day = cal.get(Calendar.DAY_OF_MONTH); cal.setTimeInMillis(0); } public static int getYear() { return cur_year; } public static int getMonth() { return cur_month; } public static int getDay() { return cur_day; } public static int getHour() { cur_hour = cal.get(Calendar.HOUR_OF_DAY); return cur_hour; } public static int getMinute() { cur_minute = cal.get(Calendar.MINUTE); return cur_minute; } public static int getSecond() { cur_second = cal.get(Calendar.SECOND); return cur_second; } public static int getMSecond() { cur_msecond = cal.get(Calendar.MILLISECOND); return cur_msecond; } public static int getCurrentDayNo() { return getDayNo(cur_year, cur_month, cur_day); } /* * Get day number from 01/01/0001 (1 AD) */ public static int getDayNo(int year, int month, int day) { cal.set(year, month, day); long dateEpochMillis = cal.getTimeInMillis(); // months start from 0 -- we need January here cal.set(1, 0, 1); long startEpochMillis = cal.getTimeInMillis(); long dateMillis = dateEpochMillis - startEpochMillis; assert(dateMillis >= 0); // return day number: 1sec = 1000msecs, 1hour = 3600secs, 1day = 24hours; 'int' should be enough return (int)(dateMillis / 1000 / 3600 / 24); } public static Date getDateFromDayNo(int dayNo) { // to msec based on 01/01/01: 1sec = 1000msecs, 1hour = 3600secs, 1day = 24hours; 'int' should be enough long dateMillis = (long)dayNo * 24 * 3600 * 1000; // months start from 0 -- we need January here cal.set(1, 0, 1); long startEpochMillis = cal.getTimeInMillis(); // we need msecs from the Epoch to set up the date long dateEpochMillis = dateMillis + startEpochMillis; cal.setTimeInMillis(dateEpochMillis); return cal.getTime(); } public static Date getDateFromYMD(int year, int month, int day) { cal.set(year, month, day); return cal.getTime(); } //TODO not thread safe public static Date getDateFromTime(int year, int month, int day, int hour, int min, int sec, int msec) { cal.set(year, month, day, hour, min, sec); cal.set(Calendar.MILLISECOND, msec); return cal.getTime(); } public static Date addDaysMsecs(Date time, int daysAdd, int msecsAdd, boolean adjustWeekend) { if (adjustWeekend) { daysAdd = ((daysAdd / TPCEConstants.daysPerWorkWeek) * 7) + (daysAdd % TPCEConstants.daysPerWorkWeek); } cal.setTime(time); cal.add(Calendar.DAY_OF_MONTH, daysAdd); cal.add(Calendar.MILLISECOND, msecsAdd); return cal.getTime(); } public static Date AddMinutes(Date date, int minutes){ return (Date)addDaysMsecs( date, 0, minutes * SecondsPerMinute * MsPerSecond, false); } public static Date AddWorkMs(Date date, long WorkMs){ int WorkDays = (int)(WorkMs / (long) MsPerWorkDay); return (Date)addDaysMsecs( date, WorkDays, (int)(WorkMs % MsPerWorkDay), true ); } public static TimestampType getTimeStamp(Date date){ return new TimestampType(date); } }