001/* Copyright (C) 2014 konik.io
002 *
003 * This file is part of the Konik library.
004 *
005 * The Konik library is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * The Konik library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with the Konik library. If not, see <http://www.gnu.org/licenses/>.
017 */
018package io.konik.zugferd.unece.codes;
019
020import static io.konik.util.KonikEnum.isKnownCode;
021import io.konik.exception.TransformationException;
022
023import java.text.ParseException;
024import java.text.SimpleDateFormat;
025import java.util.Date;
026
027/**
028 * = The Date Time Types 
029 * 
030 * Enumeration contains some of the +UNEC 2379+ codes and formats. This Enumeration does not contain periods formats.
031 *
032 * @see http://www.unece.org/trade/untdid/d13b/tred/tred2379.htm[UN/EDIFACT 2379 Date or time or period format code^]
033 */
034public enum DateTimeType {
035
036   /** The code "MMddyy". */
037   _3("MMddyy"),
038   
039   /** The code "ddMMyyyy". */
040   _4("ddMMyyyy"),
041   
042   /** The code "ddMMyyyyHHmm". */
043   _5("ddMMyyyyHHmm"),
044//   /** The code "yyyyMMB" */
045//   _6("yyyyMMB"),
046   /** The code "yyyyMMw". */
047   _7("yyyyMMw"),
048//   /** The code "yyyyMMddS" */
049//   _8("yyyyMMddS"),
050//   /** The code "yyyyMMddPP" */
051//   _9("yyyyMMddPP"),
052   /** The code " yyyyMMdd'T'HHmm". */
053   _10(" yyyyM'T'HHmm"),
054   
055   /** The code "yyMMdd". */
056   _101("yyMMdd"),
057   
058   /** The code "yyyyMMdd". */
059   _102("yyyyMMdd"),
060   
061   /** The code "yywwu". */
062   _103("yywwF"),
063//   /** The code "MMww-MMww" */
064//   _104("MMww-MMww"),
065   /** The code "yyDDD". */
066   _105("yyDDD"),
067   
068   /** The code "MMdd". */
069   _106("MMdd"),
070   
071   /** The code "DDD". */
072   _107("DDD"),
073   
074   /** The code "ww". */
075   _108("ww"),
076   
077   /** The code "MM". */
078   _109("MM"),
079   
080   /** The code "dd". */
081   _110("dd"),
082   
083   /*
084    * Date + Time
085    */
086   
087   /** The code "yyMMddHHmm". */
088   _201("yyMMddHHmm"),
089   
090   /** The code "yyMMddHHmmss". */
091   _202("yyMMddHHmmss"),
092   
093   /** The code "yyyyMMddHHmm". */
094   _203("yyyyMMddHHmm"),
095   
096   /** The code "yyyyMMddHHmmss". */
097   _204("yyyyMMddHHmmss"),
098   
099   /** The code "yyyyMMddHHmmXX". */
100   _205("yyyyMMddHHmmZ"),
101   
102   /** The code "yyMMddHHmmXX". */
103   _206("yyMMddHHmmZ"),
104   
105   /** The code "yyMMddHHmmssXX". */
106   _207("yyMMddHHmmssZ"),
107   
108   /** The code "yyyyMMddHHmmssXX". */
109   _208("yyyyMMddHHmmssZ"),
110   
111   /** The code "HHmmssXX". */
112   _209("HHmmssZ"),
113//   /** The code "HHmmssXX-HHmmssXX" */
114//   _210("HHmmssXX-HHmmssXX"),
115  
116   /** The code "yyMMddHHmmXX". */
117   _301("yyMMddHHmmZ"),
118   
119   /** The code "yyMMddHHmmssXX". */
120   _302("yyMMddHHmmssZ"),
121   
122   /** The code "yyyyMMddHHmmXX". */
123   _303("yyyyMMddHHmmZ"),
124   
125   /** The code "yyyyMMddHHmmssXX". */
126   _304("yyyyMMddHHmmssZ"),
127   
128   /** The code "MMddHHmm". */
129   _305("MMddHHmm"),
130   
131   /** The code "ddHHmm". */
132   _306("ddHHmm"),
133   
134   /** The code "HHmm". */
135   _401("HHmm"),
136   
137   /** The code "HHmmss". */
138   _402("HHmmss"),
139   
140   /** The code "HHmmssXX". */
141   _404("HHmmssZ"),
142//   /** The code "MMMMss" */
143//   _405("MMMMss"),
144//   /** The code "XX" */
145//   _406("XX"),
146//   /** The code "HHmmHHmm" */
147//   _501("HHmmHHmm"),
148//   /** The code "HHmmss-HHmmss" */
149//   _502("HHmmss-HHmmss"),
150//   /** The code "HHmmssXX-HHmmssXX" */
151//   _503("HHmmssXX-HHmmssXX"),
152//   /** The code "CC" */
153//   _600("CC"),
154   /** The code "yy". */
155   _601("yy"),
156   
157   /** The code "yyyy". */
158   _602("yyyy"),
159//   /** The code "yyS" */
160//   _603("yyS"),
161//   /** The code "yyyyS" */
162//   _604("yyyyS"),
163//   /** The code "yyyyQ" */
164//   _608("yyyyQ"),
165   /** The code "yyMM". */
166   _609("yyMM"),
167   
168   /** The code "yyyyMM". */
169   _610("yyyyMM"),
170//   /** The code "yyMMA" */
171//   _613("yyMMA"),
172//   /** The code "yyyyMMA" */
173//   _614("yyyyMMA"),
174   /** The code "yyww". */
175   _615("yyww"),
176   
177   /** The code "yyyyww". */
178   _616("yyyyww");
179//   /** The code "yy-yy" */
180//   _701("yy-yy"),
181//   /** The code "yyyy-yyyy" */
182//   _702("yyyy-yyyy"),
183//   /** The code "yyS-yyS" */
184//   _703("yyS-yyS"),
185//   /** The code "yyyyS-yyyyS" */
186//   _704("yyyyS-yyyyS"),
187//   /** The code "yyPyyP" */
188//   _705("yyPyyP"),
189//   /** The code "yyyyP-yyyyP" */
190//   _706("yyyyP-yyyyP"),
191//   /** The code "yyQ-yyQ" */
192//   _707("yyQ-yyQ"),
193//   /** The code "yyyyQ-yyyyQ" */
194//   _708("yyyyQ-yyyyQ"),
195//   /** The code "yyMM-yyMM" */
196//   _709("yyMM-yyMM"),
197//   /** The code "yyyyMM-yyyyMM" */
198//   _710("yyyyMM-yyyyMM"),
199//   /** The code "yyMMddHHmm-yyMMddHHmm" */
200//   _713("yyMMddHHmm-yyMMddHHmm"),
201//   /** The code "yyww-yyww" */
202//   _715("yyww-yyww"),
203//   /** The code "yyyyww-yyyyww" */
204//   _716("yyyyww-yyyyww"),
205//   /** The code "yyMMdd-yyMMdd" */
206//   _717("yyMMdd-yyMMdd"),
207//   /** The code "yyyyMMdd-yyyyMMdd" */
208//   _718("yyyyMMdd-yyyyMMdd"),
209//   /** The code "yyyyMMddHHmm-yyyyMMddHHmm" */
210//   _719("yyyyMMddHHmm-yyyyMMddHHmm"),
211//   /** The code "DHHmm-DHHmm" */
212//   _720("DHHmm-DHHmm"),
213//   /** The code "Year" */
214//   _801("Year"),
215//   /** The code "Month" */
216//   _802("Month"),
217//   /** The code "Week" */
218//   _803("Week"),
219//   /** The code "Day" */
220//   _804("Day"),
221//   /** The code "Hour" */
222//   _805("Hour"),
223//   /** The code "Minute" */
224//   _806("Minute"),
225//   /** The code "Second" */
226//   _807("Second"),
227//   /** The code "Semester" */
228//   _808("Semester"),
229//   /** The code "_our months period" */
230//   _809("_our months period"),
231//   /** The code "Trimester" */
232//   _810("Trimester"),
233//   /** The code "Half month" */
234//   _811("Half month"),
235//   /** The code "Ten days" */
236//   _812("Ten days"),
237//   /** The code "Day of the week" */
238//   _813("Day of the week"),
239//   /** The code "Working days" */
240//   _814("Working days");
241
242   /** The prefix of enum "_". */
243   private static final String PREFIX = "_";
244
245   /** The pattern e.g. +yyyyMMdd+ */
246   private final String pattern;
247
248   /** The thread local formatter. */
249   private final ThreadLocal<SimpleDateFormat> formatter;
250
251   /**
252    * Instantiates a new date time type.
253    *
254    * @param pattern the pattern
255    */
256   private DateTimeType(final String pattern) {
257      this.pattern = pattern;
258      this.formatter = new ThreadLocal<SimpleDateFormat>() {
259         @Override
260         protected SimpleDateFormat initialValue() {
261            return new SimpleDateFormat(pattern);
262         }
263      };
264   }
265   
266   /**
267    * Gets the code.
268    *
269    * @return the code
270    */
271   public String getCode() {
272      return name().substring(1);
273   }
274
275   /**
276    * Gets the pattern.
277    *
278    * @return the pattern
279    */
280   public String getPattern() {
281      return pattern;
282   }
283   
284
285   /**
286    * Format the given date to a string.
287    *
288    * @param date the date
289    * @return the string
290    */
291   public String format(final Date date) {
292      return formatter.get().format(date);
293   }
294
295   /**
296    * Format the given date to string.
297    *
298    * @param date the date
299    * @return the string
300    */
301   public String format(final Long date) {
302      return formatter.get().format(date);
303   }
304
305   /**
306    * Parses the given value to a date object.
307    *
308    * @param value the date value
309    * @return the parsed date
310    */
311   public Date parse(final String value) {
312      try {
313         return formatter.get().parse(value);
314      } catch (ParseException e) {
315         throw new TransformationException("Not able to read the given date value: " + value);
316      }
317   }
318
319   /**
320    * Answers if the provided +UNEC 2379+ format code is known.
321    *
322    * @param code the format code
323    * @return true, if code is known
324    */
325   public static boolean isKnown(String code) {
326      return isKnownCode(DateTimeType.class, PREFIX + code);
327   }
328
329   /**
330    * Return a DateTimeType by the given code string.
331    *
332    * @param code the date code
333    * @return the known DateTimeType
334    */
335   public static DateTimeType getByCode(String code) {
336      return DateTimeType.valueOf(PREFIX + code);
337   }
338   
339   /**
340    * Dumps the code, pattern and name as a string.
341    *
342    * @return the string
343    */
344   @Override
345   public String toString() {
346      StringBuilder builder = new StringBuilder();
347      builder.append("BasicProfile [").append("name=").append(this.name()).append(" ,pattern=").append(pattern).append("]");
348      return builder.toString();
349   }
350
351
352   
353   
354}