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 039 * or expression: 2d, 3h, 5w, 2M, 3y 040 * or a number of ms: 1234 041 * @throws IllegalArgumentException if the duration can not be parsed 042 * @return a new datetime 043 */ 044 public static DateTime plusDuration(DateTime origin, String duration) { 045 if (duration.matches("[a-zA-Z]+")) { 046 return plusDurationAsNoun(origin, duration); 047 } 048 if (duration.matches("[0-9]+")) { 049 return origin.plusMillis(Integer.valueOf(duration)); 050 } 051 return plusDurationAsExpression(origin, duration); 052 } 053 054 private static DateTime plusDurationAsExpression(DateTime origin, String duration) { 055 int k = getFactor(duration); 056 switch (duration.substring(duration.length() - 1, duration.length())) { 057 case "s": 058 return origin.plusSeconds(k); 059 case "m": 060 return origin.plusMinutes(k); 061 case "h": 062 return origin.plusHours(k); 063 case "d": 064 return origin.plusDays(k); 065 case "w": 066 return origin.plusWeeks(k); 067 case "M": 068 return origin.plusMonths(k); 069 case "y": 070 return origin.plusYears(k); 071 } 072 return invalid(duration); 073 } 074 075 private static int getFactor(String duration) { 076 try { 077 return Integer.valueOf(duration.substring(0, duration.length() - 1)); 078 } catch (NumberFormatException | StringIndexOutOfBoundsException e) { 079 invalid(duration); 080 } 081 return 1; 082 } 083 084 private static DateTime plusDurationAsNoun(DateTime origin, String duration) { 085 switch (duration.toLowerCase()) { 086 case "second": 087 return origin.plusSeconds(1); 088 case "minute": 089 return origin.plusMinutes(1); 090 case "hour": 091 return origin.plusHours(1); 092 case "day": 093 return origin.plusDays(1); 094 case "week": 095 return origin.plusWeeks(1); 096 case "month": 097 return origin.plusMonths(1); 098 case "quarter": 099 return origin.plusMonths(3); 100 case "year": 101 return origin.plusYears(1); 102 } 103 return invalid(duration); 104 } 105 106 private static DateTime invalid(String msg) { 107 throw new IllegalArgumentException("Invalid duration: " + msg); 108 } 109 110}