Package org.projecthaystack

Source Code of org.projecthaystack.HDate

//
// Copyright (c) 2011, Brian Frank
// Licensed under the Academic Free License version 3.0
//
// History:
//   06 Jun 2011  Brian Frank  Creation
//
package org.projecthaystack;

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.projecthaystack.io.HZincReader;

/**
* HDate models a date (day in year) tag value.
*
* @see <a href='http://project-haystack.org/doc/TagModel#tagKinds'>Project Haystack</a>
*/
public class HDate extends HVal
{
  /** Construct from basic fields */
  public static HDate make(int year, int month, int day)
  {
    if (year < 1900) throw new IllegalArgumentException("Invalid year");
    if (month < 1 || month > 12) throw new IllegalArgumentException("Invalid month");
    if (day < 1 || day > 31) throw new IllegalArgumentException("Invalid day");
    return new HDate(year, month, day);
  }

  /** Construct from Java calendar instance */
  public static HDate make(Calendar c)
  {
    return new HDate(c.get(Calendar.YEAR),
                     c.get(Calendar.MONTH) + 1,
                     c.get(Calendar.DAY_OF_MONTH));
  }

  /** Parse from string fomat "YYYY-MM-DD" or raise ParseException */
  public static HDate make(String s)
  {
    HVal val = new HZincReader(s).readScalar();
    if (val instanceof HDate) return (HDate)val;
    throw new ParseException(s);
  }

  /** Get HDate for current time in default timezone */
  public static HDate today()
  {
    return HDateTime.now().date;
  }

  /** Private constructor */
  private HDate(int year, int month, int day)
  {
    this.year  = year;
    this.month = month;
    this.day   = day;
  }

  /** Hash is based on year, month, day */
  public int hashCode()
  {
    return (year << 16) ^ (month << 8) ^ day;
  }

    /** Equals is based on year, month, day */
  public boolean equals(Object that)
  {
    if (!(that instanceof HDate)) return false;
    HDate x = (HDate)that;
    return year == x.year && month == x.month && day == x.day;
  }

  /** Return sort order as negative, 0, or positive */
  public int compareTo(Object that)
  {
    HDate x = (HDate)that;
    if (year < x.year)   return -1; else if (year > x.year)   return 1;
    if (month < x.month) return -1; else if (month > x.month) return 1;
    if (day < x.day)     return -1; else if (day > x.day)     return 1;
    return 0;
  }

  /** Four digit year such as 2011 */
  public final int year;

  /** Month as 1-12 (Jan is 1, Dec is 12) */
  public final int month;

  /** Day of month as 1-31 */
  public final int day;

  /** Encode as "YYYY-MM-DD" */
  public String toZinc()
  {
    StringBuffer s = new StringBuffer();
    toZinc(s);
    return s.toString();
  }

  /** Package private implementation shared with HDateTime */
  void toZinc(StringBuffer s)
  {
    s.append(year).append('-');
    if (month < 10) s.append('0'); s.append(month).append('-');
    if (day < 10) s.append('0');   s.append(day);
  }

  /** Convert this date into HDateTime for midnight in given timezone. */
  public HDateTime midnight(HTimeZone tz)
  {
    return HDateTime.make(this, HTime.MIDNIGHT, tz);
  }

  /** Return date in future given number of days */
  public HDate plusDays(int numDays)
  {
    if (numDays == 0) return this;
    if (numDays < 0) return minusDays(-numDays);
    int year  = this.year;
    int month = this.month;
    int day   = this.day;
    for (; numDays > 0; --numDays)
    {
      day++;
      if (day > daysInMonth(year, month))
      {
        day = 1;
        month++;
        if (month > 12) { month = 1; year++; }
      }
    }
    return make(year, month, day);
  }

  /** Return date in past given number of days */
  public HDate minusDays(int numDays)
  {
    if (numDays == 0) return this;
    if (numDays < 0) return plusDays(-numDays);
    int year  = this.year;
    int month = this.month;
    int day   = this.day;
    for (; numDays > 0; --numDays)
    {
      day--;
      if (day <= 0)
      {
        month--;
        if (month < 1) { month = 12; year--; }
        day = daysInMonth(year, month);
      }
    }
    return make(year, month, day);
  }

  /** Return if given year a leap year */
  public static boolean isLeapYear(int year)
  {
    if ((year & 3) != 0) return false;
    return (year % 100 != 0) || (year % 400 == 0);
  }

  /** Return number of days in given year (xxxx) and month (1-12) */
  public static int daysInMonth(int year, int mon)
  {
    return isLeapYear(year) ? daysInMonLeap[mon] : daysInMon[mon];
  }

  /** Return day of week: Sunday is 1, Saturday is 7 */
  public int weekday()
  {
    GregorianCalendar c = new GregorianCalendar(year, month-1, day);
    return c.get(Calendar.DAY_OF_WEEK);
  }

  private static final int daysInMon[]     = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  private static final int daysInMonLeap[] = { -1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

}
TOP

Related Classes of org.projecthaystack.HDate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.