You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractLocalDateField.java 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.ui;
  17. import java.text.ParseException;
  18. import java.text.SimpleDateFormat;
  19. import java.time.Instant;
  20. import java.time.LocalDate;
  21. import java.time.ZoneId;
  22. import java.time.ZoneOffset;
  23. import java.time.format.DateTimeFormatter;
  24. import java.time.format.FormatStyle;
  25. import java.time.temporal.TemporalAccessor;
  26. import java.util.Date;
  27. import java.util.Locale;
  28. import java.util.Map;
  29. import com.vaadin.data.Result;
  30. import com.vaadin.data.validator.DateRangeValidator;
  31. import com.vaadin.data.validator.RangeValidator;
  32. import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
  33. import com.vaadin.shared.ui.datefield.DateResolution;
  34. /**
  35. * Abstract DateField class for {@link LocalDate} type.
  36. *
  37. * @author Vaadin Ltd
  38. * @since 8.0
  39. */
  40. public abstract class AbstractLocalDateField
  41. extends AbstractDateField<LocalDate, DateResolution> {
  42. /**
  43. * Constructs an empty <code>AbstractLocalDateField</code> with no caption.
  44. */
  45. public AbstractLocalDateField() {
  46. super(DateResolution.DAY);
  47. }
  48. /**
  49. * Constructs an empty <code>AbstractLocalDateField</code> with caption.
  50. *
  51. * @param caption
  52. * the caption of the datefield.
  53. */
  54. public AbstractLocalDateField(String caption) {
  55. super(caption, DateResolution.DAY);
  56. }
  57. /**
  58. * Constructs a new <code>AbstractLocalDateField</code> with the given
  59. * caption and initial text contents.
  60. *
  61. * @param caption
  62. * the caption <code>String</code> for the editor.
  63. * @param value
  64. * the LocalDate value.
  65. */
  66. public AbstractLocalDateField(String caption, LocalDate value) {
  67. super(caption, value, DateResolution.DAY);
  68. }
  69. @Override
  70. protected int getDatePart(LocalDate date, DateResolution resolution) {
  71. LocalDate value = date;
  72. if (value == null) {
  73. value = LocalDate.of(1, 1, 1);
  74. }
  75. switch (resolution) {
  76. case DAY:
  77. return value.getDayOfMonth();
  78. case MONTH:
  79. return value.getMonthValue();
  80. case YEAR:
  81. return value.getYear();
  82. default:
  83. assert false : "Unexpected resolution argument " + resolution;
  84. return -1;
  85. }
  86. }
  87. @Override
  88. protected LocalDate buildDate(
  89. Map<DateResolution, Integer> resolutionValues) {
  90. return LocalDate.of(resolutionValues.get(DateResolution.YEAR),
  91. resolutionValues.getOrDefault(DateResolution.MONTH, 1),
  92. resolutionValues.getOrDefault(DateResolution.DAY, 1));
  93. }
  94. @Override
  95. protected RangeValidator<LocalDate> getRangeValidator() {
  96. return new DateRangeValidator(getDateOutOfRangeMessage(),
  97. getDate(getRangeStart(), getResolution()),
  98. getDate(getRangeEnd(), getResolution()));
  99. }
  100. @Override
  101. protected AbstractTextualDateFieldState getState() {
  102. return (AbstractTextualDateFieldState) super.getState();
  103. }
  104. @Override
  105. protected AbstractTextualDateFieldState getState(boolean markAsDirty) {
  106. return (AbstractTextualDateFieldState) super.getState(markAsDirty);
  107. }
  108. @Override
  109. protected LocalDate convertFromDate(Date date) {
  110. if (date == null) {
  111. return null;
  112. }
  113. return Instant.ofEpochMilli(date.getTime()).atZone(ZoneOffset.UTC)
  114. .toLocalDate();
  115. }
  116. @Override
  117. protected Date convertToDate(LocalDate date) {
  118. if (date == null) {
  119. return null;
  120. }
  121. return Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
  122. }
  123. private LocalDate getDate(LocalDate date, DateResolution forResolution) {
  124. if (date == null) {
  125. return null;
  126. }
  127. if (forResolution == DateResolution.YEAR) {
  128. return date.withDayOfYear(1);
  129. } else if (forResolution == DateResolution.MONTH) {
  130. return date.withDayOfMonth(1);
  131. } else {
  132. return date;
  133. }
  134. }
  135. @Override
  136. protected String formatDate(LocalDate value) {
  137. if (value == null) {
  138. return "";
  139. }
  140. DateTimeFormatter dateTimeFormatter = DateTimeFormatter
  141. .ofLocalizedDate(FormatStyle.SHORT);
  142. Locale locale = getLocale();
  143. if (locale != null) {
  144. dateTimeFormatter = dateTimeFormatter.withLocale(locale);
  145. }
  146. return value.format(dateTimeFormatter);
  147. }
  148. @Override
  149. protected LocalDate toType(TemporalAccessor temporalAccessor) {
  150. return temporalAccessor == null ? null
  151. : LocalDate.from(temporalAccessor);
  152. }
  153. @Override
  154. protected Result<LocalDate> handleUnparsableDateString(String dateString) {
  155. // Handle possible week number, which cannot be parsed client side due
  156. // limitations in GWT
  157. if (this.getDateFormat() != null && this.getDateFormat().contains("w")) {
  158. Date parsedDate;
  159. SimpleDateFormat df = new SimpleDateFormat(this.getDateFormat(),this.getLocale());
  160. try {
  161. parsedDate = df.parse(dateString);
  162. } catch (ParseException e) {
  163. return super.handleUnparsableDateString(dateString);
  164. }
  165. ZoneId zi = this.getZoneId();
  166. if (zi == null) {
  167. zi = ZoneId.systemDefault();
  168. }
  169. LocalDate date = Instant.ofEpochMilli(parsedDate.getTime()).atZone(zi).toLocalDate();
  170. return Result.ok(date);
  171. } else {
  172. return super.handleUnparsableDateString(dateString);
  173. }
  174. }
  175. }