Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You 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 org.nuiton.wikitty;
 
 /*
  * #%L
  * Wikitty :: api
  * %%
  * Copyright (C) 2009 - 2013 CodeLutin
  * %%
  * This program 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 3 of the 
  * License, or (at your option) any later version.
  * 
  * This program 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 General Lesser Public License for more details.
  * 
  * You should have received a copy of the GNU General Lesser Public 
  * License along with this program.  If not, see
  * <http://www.gnu.org/licenses/lgpl-3.0.html>.
  * #L%
  */
 
 import java.util.Date;
 import java.util.Map;
This class is copy of DateMathParser from SolR librairy, and modified to support ':' to set hour and '=' to set date. A Simple Utility class for parsing "math" like strings relating to Dates.

The basic syntax support addition, subtraction and rounding at various levels of granularity (or "units"). Commands can be chained together and are parsed from left to right. '+' and '-' denote addition and subtraction, while '/' denotes "round". Round requires only a unit, while addition/subtraction require an integer value and a unit. Command strings must not include white space, but the "No-Op" command (empty string) is allowed....

   /HOUR
      ... Round to the start of the current hour
   /DAY
      ... Round to the start of the current day
   +2YEARS
      ... Exactly two years in the future from now
   =????1130
      ... keep year but set date to 30 november
   :12??30
      ... keep minute but set hour to 12 and seconde to 30
   -1DAY
      ... Exactly 1 day prior to now
   /DAY+6MONTHS+3DAYS
      ... 6 months and 3 days in the future from the start of
          the current day
   +6MONTHS+3DAYS/DAY
      ... 6 months and 3 days in the future from now, rounded
          down to nearest day
 

(Multiple aliases exist for the various units of time (ie: MINUTE and MINUTES; MILLI, MILLIS, MILLISECOND, and MILLISECONDS.) The complete list can be found by inspecting the keySet of CALENDAR_UNITS)

All commands are relative to a "now" which is fixed in an instance of DateMathParser such that p.parseMath("+0MILLISECOND").equals(p.parseMath("+0MILLISECOND")) no matter how many wall clock milliseconds elapse between the two distinct calls to parse (Assuming no other thread calls "setNow" in the interim). The default value of 'now' is the time at the moment the DateMathParser instance is constructed, unless overridden by the NOW request param.

All commands are also affected to the rules of a specified java.util.TimeZone (including the start/end of DST if any) which determine when each arbitrary day starts. This not only impacts rounding/adding of DAYs, but also cascades to rounding of HOUR, MIN, MONTH, YEAR as well. The default TimeZone used is UTC unless overridden by the TZ request param.

See also:
SolrRequestInfo.getClientTimeZone
SolrRequestInfo.getNOW
public class DateMathParser  {
  
  public static TimeZone UTC = TimeZone.getTimeZone("UTC");

  
Default TimeZone for DateMath rounding (UTC)
  public static final TimeZone DEFAULT_MATH_TZ = ;
  
Default Locale for DateMath rounding (Locale.ROOT)
  public static final Locale DEFAULT_MATH_LOCALE = .;

  
A mapping from (uppercased) String labels idenyifying time units, to the corresponding Calendar constant used to set/add/roll that unit of measurement.

A single logical unit of time might be represented by multiple labels for convenience (ie: DATE==DAY, MILLI==MILLISECOND)

  public static final Map<String,IntegerCALENDAR_UNITS = makeUnitsMap();

  

See also:
CALENDAR_UNITS
  private static Map<String,IntegermakeUnitsMap() {
    // NOTE: consciously choosing not to support WEEK at this time,
    // because of complexity in rounding down to the nearest week
    // arround a month/year boundry.
    // (Not to mention: it's not clear what people would *expect*)
    // 
    // If we consider adding some time of "week" support, then
    // we probably need to change "Locale loc" to default to something 
    // from a param via SolrRequestInfo as well.
    
    Map<String,Integerunits = new HashMap<String,Integer>(13);
    units.put("YEAR",        .);
    units.put("YEARS",       .);
    units.put("MONTH",       .);
    units.put("MONTHS",      .);
    units.put("DAY",         .);
    units.put("DAYS",        .);
    units.put("DATE",        .);
    units.put("HOUR",        .);
    units.put("HOURS",       .);
    units.put("MINUTE",      .);
    units.put("MINUTES",     .);
    units.put("SECOND",      .);
    units.put("SECONDS",     .);
    units.put("MILLI",       .);
    units.put("MILLIS",      .);
    units.put("MILLISECOND".);
    units.put("MILLISECONDS",.);
    return units;
  }

  
Set date with pattern like 2013??01
  • ex: now=201311 conserve le jour et l'heure mais change le mois et l'annee a novembre 2013
  • ex: now=????1131 conserve l'annee mais change le mois et le jour 31 novembre
  • ex: now=???????? ne change rien

    Parameters:
    c
    pattern
  •   public static void setDate(Calendar cString pattern) {
          String year = StringUtils.substring(pattern, 0, 4);
          String month = StringUtils.substring(pattern, 4, 6);
          String day = StringUtils.substring(pattern, 6, 8);
          if (StringUtils.length(year) == 4 && StringUtils.isNumeric(year)) {
              c.set(., Integer.parseInt(year));
          }
          if (StringUtils.length(month) == 2 && StringUtils.isNumeric(month)) {
              c.set(., Integer.parseInt(month)-1); // -1 because month is 0 based
          }
          if (StringUtils.length(day) == 2 && StringUtils.isNumeric(day)) {
              c.set(., Integer.parseInt(day));
          }
      }

      
    Set hour with pattern hhmmss
  • now:1200 conserve le jour mais change l'heure a 12:00
  • now:?????? ne change rien

    Parameters:
    c
    pattern
  •   public static void setHour(Calendar cString pattern) {
          String hour = StringUtils.substring(pattern, 0, 2);
          String min = StringUtils.substring(pattern, 2, 4);
          String sec = StringUtils.substring(pattern, 4, 6);
          if (StringUtils.length(hour) == 2 && StringUtils.isNumeric(hour)) {
              c.set(., Integer.parseInt(hour));
          }
          if (StringUtils.length(min) == 2 && StringUtils.isNumeric(min)) {
              c.set(., Integer.parseInt(min));
          }
          if (StringUtils.length(sec) == 2 && StringUtils.isNumeric(sec)) {
              c.set(., Integer.parseInt(sec));
          }
      }

      
    Modifies the specified Calendar by "adding" the specified value of units

    Throws:
    java.lang.IllegalArgumentException if unit isn't recognized.
    See also:
    CALENDAR_UNITS
      public static void add(Calendar cint valString unit) {
        Integer uu = .get(unit);
        if (null == uu) {
          throw new IllegalArgumentException("Adding Unit not recognized: "
                                             + unit);
        }
        c.add(uu.intValue(), val);
      }
      
      
    Modifies the specified Calendar by "rounding" down to the specified unit

    Throws:
    java.lang.IllegalArgumentException if unit isn't recognized.
    See also:
    CALENDAR_UNITS
      public static void round(Calendar cString unit) {
        Integer uu = .get(unit);
        if (null == uu) {
          throw new IllegalArgumentException("Rounding Unit not recognized: "
                                             + unit);
        }
        int u = uu.intValue();
        
        switch (u) {
          
        case .:
          c.clear(.);
          /* fall through */
        case .:
          c.clear(.);
          c.clear(.);
          /* fall through */
        case .:
          c.clear(.);
          c.clear(.);
          c.clear(.);
          /* fall through */
        case .:
          c.clear(.);
          /* fall through */
        case .:
          c.clear(.);
          /* fall through */
        case .:
          c.clear(.);
          break;
        default:
          throw new IllegalStateException
            ("No logic for rounding value ("+u+") " + unit);
        }
      }
      
      private TimeZone zone;
      private Locale loc;
      private Date now;
      
      
    Default constructor that assumes UTC should be used for rounding unless otherwise specified in the SolrRequestInfo

    See also:
    SolrRequestInfo.getClientTimeZone
    DEFAULT_MATH_LOCALE
      public DateMathParser() {
        this(null);
        
      }

      

    Parameters:
    tz The TimeZone used for rounding (to determine when hours/days begin). If null, then this method defaults to the value dicated by the SolrRequestInfo if it exists -- otherwise it uses UTC.
    l The Locale used for rounding (to determine when weeks begin). If null, then this method defaults to en_US.
    See also:
    DEFAULT_MATH_TZ
    DEFAULT_MATH_LOCALE
    java.util.Calendar.getInstance(java.util.TimeZone,java.util.Locale)
    SolrRequestInfo.getClientTimeZone
      public DateMathParser(TimeZone tzLocale l) {
         = (null != l) ? l : ;
         = (null != tz) ? tz : ;
      }

      
    Defines this instance's concept of "now".

    See also:
    getNow()
      public void setNow(Date n) {
         = n;
      }
      
      
    Returns a cloned of this instance's concept of "now". If setNow was never called (or if null was specified) then this method first defines 'now' as the value dictated by the SolrRequestInfo if it exists -- otherwise it uses a new Date instance at the moment getNow() is first called.

    See also:
    setNow(java.util.Date)
    SolrRequestInfo.getNOW
      public Date getNow() {
        if ( == null) {
             = new Date();
        }
        return (Date).clone();
      }

      
    Parses a string of commands relative "now" are returns the resulting Date.

    Throws:
    java.text.ParseException positions in ParseExceptions are token positions, not character positions.
      public Date parseMath(String maththrows ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getNow());
        /* check for No-Op */
        if (0==math.length()) {
          return cal.getTime();
        }
        
        String[] ops = .split(math);
        // si 0 n'est pas vide, alors il y a une erreur, car on ne doit pas avoir de
        // valeur dans 0 et un operateur (:=/+-) dans 1
        if (StringUtils.length(ops[0]) != 0) {
            throw new ParseException
              ("Math expression must began with operator: \"" + ops[0] + "\"", 0);
        }
        int pos = 1; // on passe le 0 qui est vide vu la regex utilisee
        while ( pos < ops.length ) {
          if (1 != ops[pos].length()) {
            throw new ParseException
              ("Multi character command found: \"" + ops[pos] + "\""pos);
          }
          char command = ops[pos++].charAt(0);
          switch (command) {
          case '/':
            if (ops.length < pos + 1) {
              throw new ParseException
                ("Need a unit after command: \"" + command + "\""pos);
            }
            try {
              round(calops[pos++]);
            } catch (IllegalArgumentException e) {
              throw new ParseException
                ("Unit not recognized: \"" + ops[pos-1] + "\""pos-1);
            }
            break;
          case '=':
              if (ops.length < pos + 1) {
                  throw new ParseException
                          ("Need a unit after command: \"" + command + "\""pos);
              }
              setDate(calops[pos++]);
              break;
          case ':':
              if (ops.length < pos + 1) {
                  throw new ParseException
                          ("Need a unit after command: \"" + command + "\""pos);
              }
              setHour(calops[pos++]);
              break;
          case '+'/* fall through */
          case '-':
            if (ops.length < pos + 1) {
              throw new ParseException
                ("Need a value and unit for command: \"" + command + "\""pos);
            }
           String[] valueUnit = .split(ops[pos++]);
            if (valueUnit.length != 2) {
              throw new ParseException
                ("Need a value and unit for command: \"" + command + "\""pos-1);
            }
            int val = 0;
            try {
              val = Integer.valueOf(valueUnit[0]);
            } catch (NumberFormatException e) {
              throw new ParseException
                ("Not a Number: \"" + valueUnit[0] + "\""pos-1);
            }
            if ('-' == command) {
              val = 0 - val;
            }
            try {
              String unit = valueUnit[1];
              add(calvalunit);
            } catch (IllegalArgumentException e) {
              throw new ParseException
                ("Unit not recognized: \"" + valueUnit[1] + "\""pos-1);
            }
            break;
          default:
            throw new ParseException
              ("Unrecognized command: \"" + command + "\""pos-1);
          }
        }
        
        return cal.getTime();
      }
      private static Pattern splitter = Pattern.compile("(?<=[+=:/-])|(?=[+=:/-])");
      private static Pattern splitter2 = Pattern.compile("(?<=\\d)(?=\\D)");
    //  private static Pattern splitter = Pattern.compile("\\b|(?<=\\d|\\?)(?=\\D)");
      
    New to GrepCode? Check out our FAQ X