001/* 002 * Zmanim Java API 003 * Copyright (C) 2004-2020 Eliyahu Hershfeld 004 * 005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 006 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied 010 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 011 * details. 012 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 013 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA, 014 * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 015 */ 016package com.kosherjava.zmanim.util; 017 018import java.util.Comparator; 019import java.util.Date; 020 021/** 022 * A wrapper class for a astronomical times / <em>zmanim</em> that is mostly intended to allow sorting collections of astronomical times. 023 * It has fields for both date/time and duration based <em>zmanim</em>, name / labels as well as a longer description or explanation of a 024 * <em>zman</em>. 025 * 026 * Here is an example of various ways of sorting <em>zmanim</em>. 027 * <p>First create the Calendar for the location you would like to calculate: 028 * 029 * <pre style="background: #FEF0C9; display: inline-block;"> 030 * String locationName = "Lakewood, NJ"; 031 * double latitude = 40.0828; // Lakewood, NJ 032 * double longitude = -74.2094; // Lakewood, NJ 033 * double elevation = 20; // optional elevation correction in Meters 034 * // the String parameter in getTimeZone() has to be a valid timezone listed in {@link java.util.TimeZone#getAvailableIDs()} 035 * TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); 036 * GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone); 037 * ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location); 038 * Zman sunset = new Zman(czc.getSunset(), "Sunset"); 039 * Zman shaah16 = new Zman(czc.getShaahZmanis16Point1Degrees(), "Shaah zmanis 16.1"); 040 * Zman sunrise = new Zman(czc.getSunrise(), "Sunrise"); 041 * Zman shaah = new Zman(czc.getShaahZmanisGra(), "Shaah zmanis GRA"); 042 * ArrayList<Zman> zl = new ArrayList<Zman>(); 043 * zl.add(sunset); 044 * zl.add(shaah16); 045 * zl.add(sunrise); 046 * zl.add(shaah); 047 * //will sort sunset, shaah 1.6, sunrise, shaah GRA 048 * System.out.println(zl); 049 * Collections.sort(zl, Zman.DATE_ORDER); 050 * // will sort sunrise, sunset, shaah, shaah 1.6 (the last 2 are not in any specific order) 051 * Collections.sort(zl, Zman.DURATION_ORDER); 052 * // will sort sunrise, sunset (the first 2 are not in any specific order), shaah GRA, shaah 1.6 053 * Collections.sort(zl, Zman.NAME_ORDER); 054 * // will sort shaah 1.6, shaah GRA, sunrise, sunset 055 * </pre> 056 * 057 * @author © Eliyahu Hershfeld 2007-2020 058 * @todo Add secondary sorting. As of now the {@code Comparator}s in this class do not sort by secondary order. This means that when sorting a 059 * {@link java.util.Collection} of <em>zmanim</em> and using the {@link #DATE_ORDER} {@code Comparator} will have the duration based <em>zmanim</em> 060 * at the end, but they will not be sorted by duration. This should be N/A for label based sorting. 061 */ 062public class Zman { 063 /** 064 * The name / label of the <em>zman</em>. 065 */ 066 private String label; 067 068 /** 069 * The {@link Date} of the <em>zman</em> 070 */ 071 private Date zman; 072 073 /** 074 * The duration if the <em>zman</em> is a {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various 075 * <em>shaah zmanis</em> base times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() <em>shaah Zmanis GRA</em>} or 076 * {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getShaahZmanis16Point1Degrees() <em>shaah Zmanis 16.1°</em>}). 077 */ 078 private long duration; 079 080 /** 081 * A longer description or explanation of a <em>zman</em>. 082 */ 083 private String description; 084 085 /** 086 * The constructor setting a {@link Date} based <em>zman</em> and a label. 087 * @param date the Date of the <em>zman</em>. 088 * @param label the label of the <em>zman</em> such as "<em>Sof Zman Krias Shema GRA</em>". 089 * @see #Zman(long, String) 090 */ 091 public Zman(Date date, String label) { 092 this.label = label; 093 this.zman = date; 094 } 095 096 /** 097 * The constructor setting a duration based <em>zman</em> such as 098 * {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various <em>shaah zmanis</em> times such as 099 * {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() <em>shaah zmanis GRA</em>} or 100 * {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getShaahZmanis16Point1Degrees() <em>shaah Zmanis 16.1°</em>}) and label. 101 * @param duration a duration based <em>zman</em> such as ({@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour()} 102 * @param label the label of the <em>zman</em> such as "<em>Shaah Zmanis GRA</em>". 103 * @see #Zman(Date, String) 104 */ 105 public Zman(long duration, String label) { 106 this.label = label; 107 this.duration = duration; 108 } 109 110 /** 111 * Returns the {@code Date} based <em>zman</em>. 112 * @return the <em>zman</em>. 113 * @see #setZman(Date) 114 */ 115 public Date getZman() { 116 return this.zman; 117 } 118 119 /** 120 * Sets a {@code Date} based <em>zman</em>. 121 * @param date a {@code Date} based <em>zman</em> 122 * @see #getZman() 123 */ 124 public void setZman(Date date) { 125 this.zman = date; 126 } 127 128 /** 129 * Returns a duration based <em>zman</em> such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} 130 * (or the various <em>shaah zmanis</em> times such as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() <em>shaah zmanis GRA</em>} 131 * or {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getShaahZmanis16Point1Degrees() <em>shaah zmanis 16.1°</em>}). 132 * @return the duration based <em>zman</em>. 133 * @see #setDuration(long) 134 */ 135 public long getDuration() { 136 return this.duration; 137 } 138 139 /** 140 * Sets a duration based <em>zman</em> such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} 141 * (or the various <em>shaah zmanis</em> times as {@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() <em>shaah zmanis GRA</em>} or 142 * {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getShaahZmanis16Point1Degrees() <em>shaah zmanis 16.1°</em>}). 143 * @param duration duration based <em>zman</em> such as {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour()}. 144 * @see #getDuration() 145 */ 146 public void setDuration(long duration) { 147 this.duration = duration; 148 } 149 150 /** 151 * Returns the name / label of the <em>zman</em> such as "<em>Sof Zman Krias Shema GRA</em>". There are no automatically set labels 152 * and you must set them using {@link #setLabel(String)}. 153 * @return the name/label of the <em>zman</em>. 154 * @see #setLabel(String) 155 */ 156 public String getLabel() { 157 return this.label; 158 } 159 160 /** 161 * Sets the the name / label of the <em>zman</em> such as "<em>Sof Zman Krias Shema GRA</em>". 162 * @param label the name / label to set for the <em>zman</em>. 163 * @see #getLabel() 164 */ 165 public void setLabel(String label) { 166 this.label = label; 167 } 168 169 /** 170 * Returns the longer description or explanation of a <em>zman</em>. There is no default value for this and it must be set using 171 * {@link #setDescription(String)} 172 * @return the description or explanation of a <em>zman</em>. 173 * @see #setDescription(String) 174 */ 175 public String getDescription() { 176 return this.description; 177 } 178 179 /** 180 * Sets the longer description or explanation of a <em>zman</em>. 181 * @param description 182 * the <em>zman</em> description to set. 183 * @see #getDescription() 184 */ 185 public void setDescription(String description) { 186 this.description = description; 187 } 188 189 /** 190 * A {@link Comparator} that will compare and sort <em>zmanim</em> by date/time order. Compares its two arguments by the zman's date/time 191 * order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater 192 * than the second. 193 * Please note that this class will handle cases where either the {@code Zman} is a null or {@link #getZman()} returns a null. 194 */ 195 public static final Comparator<Zman> DATE_ORDER = new Comparator<Zman>() { 196 public int compare(Zman zman1, Zman zman2) { 197 long firstTime = (zman1 == null || zman1.getZman() == null) ? Long.MAX_VALUE : zman1.getZman().getTime(); 198 long secondTime = (zman2 == null || zman2.getZman() == null) ? Long.MAX_VALUE : zman2.getZman().getTime(); 199 return Long.valueOf(firstTime).compareTo(Long.valueOf(secondTime)); 200 } 201 }; 202 203 /** 204 * A {@link Comparator} that will compare and sort zmanim by zmanim label order. Compares its two arguments by the zmanim label 205 * name order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater 206 * than the second. 207 * Please note that this class will will sort cases where either the {@code Zman} is a null or {@link #label} returns a null 208 * as empty {@code String}s. 209 */ 210 public static final Comparator<Zman> NAME_ORDER = new Comparator<Zman>() { 211 public int compare(Zman zman1, Zman zman2) { 212 String firstLabel = (zman1 == null || zman1.getLabel() == null) ? "" : zman1.getLabel(); 213 String secondLabel = (zman2 == null || zman2.getLabel() == null) ? "" : zman2.getLabel(); 214 return firstLabel.compareTo(secondLabel); 215 } 216 }; 217 218 /** 219 * A {@link Comparator} that will compare and sort duration based <em>zmanim</em> such as 220 * {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour} (or the various <em>shaah zmanis</em> times 221 * such as <em>{@link com.kosherjava.zmanim.ZmanimCalendar#getShaahZmanisGra() shaah zmanis GRA}</em> or 222 * {@link com.kosherjava.zmanim.ComplexZmanimCalendar#getShaahZmanis16Point1Degrees() <em>shaah zmanis 16.1°</em>}). Returns a negative 223 * integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. 224 * Please note that this class will will sort cases where {@code Zman} is a null. 225 */ 226 public static final Comparator<Zman> DURATION_ORDER = new Comparator<Zman>() { 227 public int compare(Zman zman1, Zman zman2) { 228 long firstDuration = zman1 == null ? Long.MAX_VALUE : zman1.getDuration(); 229 long secondDuration = zman2 == null ? Long.MAX_VALUE : zman2.getDuration(); 230 return firstDuration == secondDuration ? 0 : firstDuration > secondDuration ? 1 : -1; 231 } 232 }; 233 234 /** 235 * @see java.lang.Object#toString() 236 */ 237 public String toString() { 238 StringBuilder sb = new StringBuilder(); 239 sb.append("\nLabel:\t\t\t").append(this.getLabel()); 240 sb.append("\nZman:\t\t\t").append(getZman()); 241 sb.append("\nDuration:\t\t\t").append(getDuration()); 242 sb.append("\nDescription:\t\t\t").append(getDescription()); 243 return sb.toString(); 244 } 245}