Java tutorial
/* * Copyright 2013 Rackspace * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.rackspacecloud.blueflood.utils; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DateTimeParser { public static DateTime parse(String dateTimeOffsetString) { String stringToParse = dateTimeOffsetString.replace(" ", "").replace(",", "").replace("_", ""); if (StringUtils.isNumeric(stringToParse) && !isLikelyDateTime(stringToParse)) return dateTimeFromTimestamp(stringToParse); DateTime dateTime = tryParseDateTime("HH:mmyyyyMMdd", stringToParse); if (dateTime != null) return dateTime; List<String> splitList = splitDateTimeAndOffset(stringToParse); String offset = splitList.get(1); String dateTimeString = splitList.get(0); DateTimeOffsetParser parser = new DateTimeOffsetParser(dateTimeString, offset); return parser.updateDateTime(new DateTime()); } private static class DateTimeOffsetParser { private String dateTime = ""; private String offset = ""; public DateTimeOffsetParser(String dateTimeString, String offsetString) { this.dateTime = dateTimeString; this.offset = offsetString; } public DateTime updateDateTime(DateTime baseDateTime) { baseDateTime = extractAndUpdateTime(baseDateTime); baseDateTime = extractAndUpdateDate(baseDateTime); if (!offset.equals("")) baseDateTime = updateDateTimeWithOffset(baseDateTime); return baseDateTime; } private DateTime updateDateTimeWithOffset(DateTime baseDateTime) { if (offset.equals("")) return baseDateTime; Pattern p = Pattern.compile("(-?\\d*)([a-z]*)"); Matcher m = p.matcher(offset); if (!m.matches()) return baseDateTime; int count = Integer.parseInt(m.group(1)); String unit = m.group(2); DateTime dateTimeWithOffset = baseDateTime; if (unit.startsWith("s")) dateTimeWithOffset = baseDateTime.plusSeconds(count); else if (unit.startsWith("min")) dateTimeWithOffset = baseDateTime.plusMinutes(count); else if (unit.startsWith("h")) dateTimeWithOffset = baseDateTime.plusHours(count); else if (unit.startsWith("d")) dateTimeWithOffset = baseDateTime.plusDays(count); else if (unit.startsWith("mon")) dateTimeWithOffset = baseDateTime.plusMonths(count); else if (unit.startsWith("y")) dateTimeWithOffset = baseDateTime.plusYears(count); return dateTimeWithOffset; } private DateTime extractAndUpdateTime(DateTime inputDateTime) { DateTime resultDateTime = inputDateTime.withSecondOfMinute(0).withMillisOfSecond(0); if (dateTime.equals("") || dateTime.contains("now")) return resultDateTime; int hour = 0; int minute = 0; Pattern p = Pattern.compile("(\\d{1,2}):(\\d{2})([a|p]m)?(.*)"); Matcher m = p.matcher(dateTime); if (m.matches()) { hour = Integer.parseInt(m.group(1)); minute = Integer.parseInt(m.group(2)); String middayModifier = m.group(3); if (middayModifier != null && middayModifier.equals("pm")) hour = (hour + 12) % 24; dateTime = m.group(4); } if (dateTime.contains("noon")) { hour = 12; dateTime = dateTime.replace("noon", ""); } else if (dateTime.contains("teatime")) { hour = 16; dateTime = dateTime.replace("teatime", ""); } else if (dateTime.contains("midnight")) dateTime = dateTime.replace("midnight", ""); return resultDateTime.withHourOfDay(hour).withMinuteOfHour(minute); } private DateTime extractAndUpdateDate(DateTime resultDateTime) { String stringToParse = this.dateTime; if (stringToParse.contains("tomorrow")) { resultDateTime = resultDateTime.plusDays(1); stringToParse = stringToParse.replace("tomorrow", ""); } else if (stringToParse.contains("yesterday")) { resultDateTime = resultDateTime.minusDays(1); stringToParse = stringToParse.replace("yesterday", ""); } else if (stringToParse.contains("today")) stringToParse = stringToParse.replace("today", ""); String[] datePatterns = { "MM/dd/YY", "MM/dd/YYYY", "YYYYMMdd", "MMMMddYYYY" }; for (String s : datePatterns) { DateTime date = tryParseDateTime(s, stringToParse); if (date != null) { resultDateTime = resultDateTime.withDate(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth()); break; } } // Keep original datetime year String monthDayOptionalYearFormat = "MMMMdd"; DateTime date = tryParseDateTime(monthDayOptionalYearFormat, stringToParse); if (date != null) resultDateTime = resultDateTime.withDate(resultDateTime.getYear(), date.getMonthOfYear(), date.getDayOfMonth()); // Keep as much of original datetime as possible String dayOfWeekFormat = "EEE"; date = tryParseDateTime(dayOfWeekFormat, stringToParse); if (date != null) while (resultDateTime.getDayOfWeek() != date.getDayOfWeek()) resultDateTime = resultDateTime.minusDays(1); return resultDateTime; } } private static List<String> splitDateTimeAndOffset(String stringToSplit) { String offset = ""; String dateTimeString = stringToSplit; if (stringToSplit.contains("+")) { String[] offsetSplit = stringToSplit.split("\\+", 2); dateTimeString = offsetSplit[0]; offset = offsetSplit.length > 1 ? offsetSplit[1] : ""; } else if (stringToSplit.contains("-")) { String[] offsetSplit = stringToSplit.split("-", 2); dateTimeString = offsetSplit[0]; offset = offsetSplit.length > 1 ? "-" + offsetSplit[1] : ""; } return Arrays.asList(dateTimeString, offset); } private static DateTime dateTimeFromTimestamp(String stringToParse) { return new DateTime(Long.parseLong(stringToParse) * 1000); } private static DateTime tryParseDateTime(String format, String dateTime) { DateTime resultDateTime; try { resultDateTime = DateTimeFormat.forPattern(format).parseDateTime(dateTime); } catch (IllegalArgumentException e) { resultDateTime = null; } return resultDateTime; } private static boolean isLikelyDateTime(String stringToParse) { return stringToParse.length() == 8 && Integer.parseInt(stringToParse.substring(0, 4)) > 1900 && Integer.parseInt(stringToParse.substring(4, 6)) < 13 && Integer.parseInt(stringToParse.substring(6)) < 32; } }