001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.swaps; 018 019import java.time.*; 020import java.time.format.*; 021import java.time.temporal.*; 022import java.util.*; 023 024import org.apache.juneau.*; 025import org.apache.juneau.internal.*; 026import org.apache.juneau.swap.*; 027 028/** 029 * Swap that converts {@link Date} objects to and from strings. 030 * 031 * <p> 032 * Uses the {@link DateTimeFormatter} class for converting {@link Date} objects. 033 * 034 * <h5 class='section'>See Also:</h5><ul> 035 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SwapBasics">Swap Basics</a> 036 * </ul> 037 */ 038public class TemporalDateSwap extends StringSwap<Date> { 039 040 /** 041 * Default swap to {@link DateTimeFormatter#BASIC_ISO_DATE}. 042 * <p> 043 * Example: <js>"20111203"</js> 044 */ 045 public static class BasicIsoDate extends TemporalDateSwap { 046 047 /** Default instance.*/ 048 public static final TemporalDateSwap DEFAULT = new BasicIsoDate(); 049 050 /** Constructor.*/ 051 public BasicIsoDate() { 052 super("BASIC_ISO_DATE"); 053 } 054 } 055 056 /** 057 * Default swap to {@link DateTimeFormatter#ISO_DATE}. 058 * <p> 059 * Example: <js>"2011-12-03+01:00"</js> or <js>"2011-12-03"</js> 060 */ 061 public static class IsoDate extends TemporalDateSwap { 062 063 /** Default instance.*/ 064 public static final TemporalDateSwap DEFAULT = new IsoDate(); 065 066 /** Constructor.*/ 067 public IsoDate() { 068 super("ISO_DATE"); 069 } 070 } 071 072 /** 073 * Default swap to {@link DateTimeFormatter#ISO_DATE_TIME}. 074 * <p> 075 * Example: <js>"2011-12-03T10:15:30+01:00[Europe/Paris]"</js> 076 */ 077 public static class IsoDateTime extends TemporalDateSwap { 078 079 /** Default instance.*/ 080 public static final TemporalDateSwap DEFAULT = new IsoDateTime(); 081 082 /** Constructor.*/ 083 public IsoDateTime() { 084 super("ISO_DATE_TIME"); 085 } 086 } 087 088 /** 089 * Default swap to {@link DateTimeFormatter#ISO_INSTANT}. 090 * <p> 091 * Example: <js>"2011-12-03T10:15:30Z"</js> 092 */ 093 public static class IsoInstant extends TemporalDateSwap { 094 095 /** Default instance.*/ 096 public static final TemporalDateSwap DEFAULT = new IsoInstant(); 097 098 /** Constructor.*/ 099 public IsoInstant() { 100 super("ISO_INSTANT"); 101 } 102 } 103 104 /** 105 * Default swap to {@link DateTimeFormatter#ISO_LOCAL_DATE}. 106 * <p> 107 * Example: <js>"2011-12-03"</js> 108 */ 109 public static class IsoLocalDate extends TemporalDateSwap { 110 111 /** Default instance.*/ 112 public static final TemporalDateSwap DEFAULT = new IsoLocalDate(); 113 114 /** Constructor.*/ 115 public IsoLocalDate() { 116 super("ISO_LOCAL_DATE"); 117 } 118 } 119 120 /** 121 * Default swap to {@link DateTimeFormatter#ISO_LOCAL_DATE_TIME}. 122 * <p> 123 * Example: <js>"2011-12-03T10:15:30"</js> 124 */ 125 public static class IsoLocalDateTime extends TemporalDateSwap { 126 127 /** Default instance.*/ 128 public static final TemporalDateSwap DEFAULT = new IsoLocalDateTime(); 129 130 /** Constructor.*/ 131 public IsoLocalDateTime() { 132 super("ISO_LOCAL_DATE_TIME"); 133 } 134 } 135 136 /** 137 * Default swap to {@link DateTimeFormatter#ISO_LOCAL_TIME}. 138 * <p> 139 * Example: <js>"10:15:30"</js> 140 */ 141 public static class IsoLocalTime extends TemporalDateSwap { 142 143 /** Default instance.*/ 144 public static final TemporalDateSwap DEFAULT = new IsoLocalTime(); 145 146 /** Constructor.*/ 147 public IsoLocalTime() { 148 super("ISO_LOCAL_TIME"); 149 } 150 } 151 152 /** 153 * Default swap to {@link DateTimeFormatter#ISO_OFFSET_DATE}. 154 * <p> 155 * Example: <js>"2011-12-03"</js> 156 */ 157 public static class IsoOffsetDate extends TemporalDateSwap { 158 159 /** Default instance.*/ 160 public static final TemporalDateSwap DEFAULT = new IsoOffsetDate(); 161 162 /** Constructor.*/ 163 public IsoOffsetDate() { 164 super("ISO_OFFSET_DATE"); 165 } 166 } 167 168 /** 169 * Default swap to {@link DateTimeFormatter#ISO_OFFSET_DATE_TIME}. 170 * <p> 171 * Example: <js>"2011-12-03T10:15:30+01:00"</js> 172 */ 173 public static class IsoOffsetDateTime extends TemporalDateSwap { 174 175 /** Default instance.*/ 176 public static final TemporalDateSwap DEFAULT = new IsoOffsetDateTime(); 177 178 /** Constructor.*/ 179 public IsoOffsetDateTime() { 180 super("ISO_OFFSET_DATE_TIME"); 181 } 182 } 183 184 /** 185 * Default swap to {@link DateTimeFormatter#ISO_OFFSET_TIME}. 186 * <p> 187 * Example: <js>"10:15:30+01:00"</js> 188 */ 189 public static class IsoOffsetTime extends TemporalDateSwap { 190 191 /** Default instance.*/ 192 public static final TemporalDateSwap DEFAULT = new IsoOffsetTime(); 193 194 /** Constructor.*/ 195 public IsoOffsetTime() { 196 super("ISO_OFFSET_TIME"); 197 } 198 } 199 200 /** 201 * Default swap to {@link DateTimeFormatter#ISO_ORDINAL_DATE}. 202 * <p> 203 * Example: <js>"2012-337"</js> 204 */ 205 public static class IsoOrdinalDate extends TemporalDateSwap { 206 207 /** Default instance.*/ 208 public static final TemporalDateSwap DEFAULT = new IsoOrdinalDate(); 209 210 /** Constructor.*/ 211 public IsoOrdinalDate() { 212 super("ISO_ORDINAL_DATE"); 213 } 214 } 215 216 /** 217 * Default swap to {@link DateTimeFormatter#ISO_TIME}. 218 * <p> 219 * Example: <js>"10:15:30+01:00"</js> or <js>"10:15:30"</js> 220 */ 221 public static class IsoTime extends TemporalDateSwap { 222 223 /** Default instance.*/ 224 public static final TemporalDateSwap DEFAULT = new IsoTime(); 225 226 /** Constructor.*/ 227 public IsoTime() { 228 super("ISO_TIME"); 229 } 230 } 231 232 /** 233 * Default swap to {@link DateTimeFormatter#ISO_WEEK_DATE}. 234 * <p> 235 * Example: <js>"2012-W48-6"</js> 236 */ 237 public static class IsoWeekDate extends TemporalDateSwap { 238 239 /** Default instance.*/ 240 public static final TemporalDateSwap DEFAULT = new IsoWeekDate(); 241 242 /** Constructor.*/ 243 public IsoWeekDate() { 244 super("ISO_WEEK_DATE"); 245 } 246 } 247 248 /** 249 * Default swap to {@link DateTimeFormatter#ISO_ZONED_DATE_TIME}. 250 * <p> 251 * Example: <js>"2011-12-03T10:15:30+01:00[Europe/Paris]"</js> 252 */ 253 public static class IsoZonedDateTime extends TemporalDateSwap { 254 255 /** Default instance.*/ 256 public static final TemporalDateSwap DEFAULT = new IsoZonedDateTime(); 257 258 /** Constructor.*/ 259 public IsoZonedDateTime() { 260 super("ISO_ZONED_DATE_TIME"); 261 } 262 } 263 264 /** 265 * Default swap to {@link DateTimeFormatter#RFC_1123_DATE_TIME}. 266 * <p> 267 * Example: <js>"Tue, 3 Jun 2008 11:05:30 GMT"</js> 268 */ 269 public static class Rfc1123DateTime extends TemporalDateSwap { 270 271 /** Default instance.*/ 272 public static final TemporalDateSwap DEFAULT = new Rfc1123DateTime(); 273 274 /** Constructor.*/ 275 public Rfc1123DateTime() { 276 super("RFC_1123_DATE_TIME"); 277 } 278 } 279 280 281 private final DateTimeFormatter formatter; 282 283 /** 284 * Constructor. 285 * 286 * @param pattern The timestamp format or name of predefined {@link DateTimeFormatter}. 287 */ 288 public TemporalDateSwap(String pattern) { 289 super(Date.class); 290 this.formatter = DateUtils.getFormatter(pattern); 291 } 292 293 @Override /* ObjectSwap */ 294 public String swap(BeanSession session, Date o) throws Exception { 295 if (o == null) 296 return null; 297 return formatter.format(o.toInstant().atZone(session.getTimeZoneId())); 298 } 299 300 @Override /* ObjectSwap */ 301 public Date unswap(BeanSession session, String f, ClassMeta<?> hint) throws Exception { 302 if (f == null) 303 return null; 304 ZoneId offset = session.getTimeZoneId(); 305 TemporalAccessor ta = new DefaultingTemporalAccessor(formatter.parse(f), offset); 306 return Date.from(ZonedDateTime.from(ta).toInstant()); 307 } 308}