001/* 002 * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bdelbosc 018 */ 019package org.nuxeo.elasticsearch.aggregate; 020 021import org.joda.time.DateTime; 022 023/** 024 * Helper to add duration to a date with the same format as ES Date histogram interval 025 * 026 * @since 8.4 027 */ 028public final class DateHelper { 029 030 private DateHelper() { 031 032 } 033 034 /** 035 * Returns a new datetime plus the specified duration. 036 * 037 * @param origin the initial datetime 038 * @param duration can be expressed with a noun: hour, day, month, quarter, year or expression: 2d, 3h, 5w, 2M, 3y 039 * or a number of ms: 1234 040 * @throws IllegalArgumentException if the duration cannot be parsed 041 * @return a new datetime 042 */ 043 public static DateTime plusDuration(DateTime origin, String duration) { 044 if (duration.matches("[a-zA-Z]+")) { 045 return plusDurationAsNoun(origin, duration); 046 } 047 if (duration.matches("[0-9]+")) { 048 return origin.plusMillis(Integer.valueOf(duration)); 049 } 050 return plusDurationAsExpression(origin, duration); 051 } 052 053 private static DateTime plusDurationAsExpression(DateTime origin, String duration) { 054 int k = getFactor(duration); 055 switch (duration.substring(duration.length() - 1, duration.length())) { 056 case "s": 057 return origin.plusSeconds(k); 058 case "m": 059 return origin.plusMinutes(k); 060 case "h": 061 return origin.plusHours(k); 062 case "d": 063 return origin.plusDays(k); 064 case "w": 065 return origin.plusWeeks(k); 066 case "M": 067 return origin.plusMonths(k); 068 case "y": 069 return origin.plusYears(k); 070 } 071 return invalid(duration); 072 } 073 074 private static int getFactor(String duration) { 075 try { 076 return Integer.valueOf(duration.substring(0, duration.length() - 1)); 077 } catch (NumberFormatException | StringIndexOutOfBoundsException e) { 078 invalid(duration); 079 } 080 return 1; 081 } 082 083 private static DateTime plusDurationAsNoun(DateTime origin, String duration) { 084 switch (duration.toLowerCase()) { 085 case "second": 086 return origin.plusSeconds(1); 087 case "minute": 088 return origin.plusMinutes(1); 089 case "hour": 090 return origin.plusHours(1); 091 case "day": 092 return origin.plusDays(1); 093 case "week": 094 return origin.plusWeeks(1); 095 case "month": 096 return origin.plusMonths(1); 097 case "quarter": 098 return origin.plusMonths(3); 099 case "year": 100 return origin.plusYears(1); 101 } 102 return invalid(duration); 103 } 104 105 private static DateTime invalid(String msg) { 106 throw new IllegalArgumentException("Invalid duration: " + msg); 107 } 108 109}