/** * DateParser * Copyright 09.04.2015 by Michael Peter Christen, @0rb1t3r * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in the file lgpl21.txt * If not, see <http://www.gnu.org/licenses/>. */ package org.loklak.tools; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; import java.util.concurrent.TimeUnit; public class DateParser { public final static long HOUR_MILLIS = 60 * 60 * 1000; public final static long DAY_MILLIS = HOUR_MILLIS * 24; public final static long WEEK_MILLIS = DAY_MILLIS * 7; public final static String PATTERN_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; // pattern for a W3C datetime variant of a non-localized ISO8601 date public final static String PATTERN_ISO8601MILLIS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; // same with milliseconds public final static String PATTERN_MONTHDAY = "yyyy-MM-dd"; // the twitter search modifier format public final static String PATTERN_MONTHDAYHOURMINUTE = "yyyy-MM-dd HH:mm"; // this is the format which morris.js understands for date-histogram graphs /** Date formatter/non-sloppy parser for W3C datetime (ISO8601) in GMT/UTC */ public final static SimpleDateFormat iso8601Format = new SimpleDateFormat(PATTERN_ISO8601, Locale.US); public final static SimpleDateFormat iso8601MillisFormat = new SimpleDateFormat(PATTERN_ISO8601MILLIS, Locale.US); public final static DateFormat dayDateFormat = new SimpleDateFormat(PATTERN_MONTHDAY, Locale.US); public final static DateFormat minuteDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); public final static DateFormat secondDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); public final static Calendar UTCCalendar = Calendar.getInstance(); public final static TimeZone UTCtimeZone = TimeZone.getTimeZone("UTC"); static { UTCCalendar.setTimeZone(UTCtimeZone); dayDateFormat.setCalendar(UTCCalendar); minuteDateFormat.setCalendar(UTCCalendar); secondDateFormat.setCalendar(UTCCalendar); } /** * parse a date string for a given time zone * @param dateString in format "yyyy-MM-dd", "yyyy-MM-dd HH:mm" or "yyyy-MM-dd_HH:mm" * @param timezoneOffset number of minutes, must be negative for locations east of UTC and positive for locations west of UTC * @return a calender object representing the parsed date * @throws ParseException if the format of the date string is not well-formed */ public static Calendar parse(String dateString, final int timezoneOffset) throws ParseException { Calendar cal = Calendar.getInstance(UTCtimeZone); if ("now".equals(dateString)) return cal; if ("hour".equals(dateString)) {cal.setTime(oneHourAgo()); return cal;} if ("day".equals(dateString)) {cal.setTime(oneDayAgo()); return cal;} if ("week".equals(dateString)) {cal.setTime(oneWeekAgo()); return cal;} dateString = dateString.replaceAll("_", " "); int p = -1; if ((p = dateString.indexOf(':')) > 0) { if (dateString.indexOf(':', p + 1) > 0) synchronized (secondDateFormat) { cal.setTime(secondDateFormat.parse(dateString)); } else synchronized (minuteDateFormat) { cal.setTime(minuteDateFormat.parse(dateString)); } } else synchronized (dayDateFormat) { cal.setTime(dayDateFormat.parse(dateString)); } cal.add(Calendar.MINUTE, timezoneOffset); // add a correction; i.e. for UTC+1 -60 minutes is added to patch a time given in UTC+1 to the actual time at UTC return cal; } public static String toPostDate(Date d) { return secondDateFormat.format(d).replace(' ', '_'); } public static int getTimezoneOffset() { Calendar calendar = new GregorianCalendar(); TimeZone timeZone = calendar.getTimeZone(); return - (int) TimeUnit.MILLISECONDS.toMinutes(timeZone.getRawOffset()); // we negate the offset because thats the value which is provided by the browser as well } public static Date oneHourAgo() { return new Date(System.currentTimeMillis() - HOUR_MILLIS); } public static Date oneDayAgo() { return new Date(System.currentTimeMillis() - DAY_MILLIS); } public static Date oneWeekAgo() { return new Date(System.currentTimeMillis() - WEEK_MILLIS); } public static void main(String[] args) { Calendar calendar = new GregorianCalendar(); TimeZone timeZone = calendar.getTimeZone(); System.out.println("the date is : " + calendar.getTime().getTime()); System.out.println("the timezoneOffset is : " + getTimezoneOffset()); String postDate = toPostDate(calendar.getTime()); System.out.println("the post date is : " + postDate); try { System.out.println("post date to date : " + parse(postDate, getTimezoneOffset()).getTime().getTime()); } catch (ParseException e) { e.printStackTrace(); } } }