All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jfxtras.internal.scene.control.skin.DateTimeToCalendarHelper Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2011-2021, JFXtras
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *    Neither the name of the organization nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL JFXTRAS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package jfxtras.internal.scene.control.skin;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.WeakHashMap;

import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

/**
 *
 * @author user
 */
public class DateTimeToCalendarHelper {

	/**
	 * 
	 * @param localDate
	 * @return
	 */
	public static Calendar createCalendarFromLocalDate(LocalDate localDate, TimeZone timeZone, Locale locale)
	{
		if (localDate == null) {
			return null;
		}
		Calendar lCalendar = Calendar.getInstance(timeZone, locale);
		lCalendar.set(Calendar.YEAR, localDate.getYear());
		lCalendar.set(Calendar.MONTH, localDate.getMonth().getValue() - 1);
		lCalendar.set(Calendar.DATE, localDate.getDayOfMonth());
		lCalendar.set(Calendar.HOUR_OF_DAY, 0);
		lCalendar.set(Calendar.MINUTE, 0);
		lCalendar.set(Calendar.SECOND, 0);
		lCalendar.set(Calendar.MILLISECOND, 0);
		return lCalendar;
	}
	
	/**
	 * 
	 * @param zonedDateTime
	 * @return
	 */
	public static Calendar createCalendarFromZonedDateTime(ZonedDateTime zonedDateTime)
	{
		if (zonedDateTime == null) {
			return null;
		}
		Calendar lCalendar = GregorianCalendar.from(zonedDateTime);
		return lCalendar;
	}
	
	/**
	 * 
	 * @param localDateTime
	 * @return
	 */
	public static Calendar createCalendarFromLocalDateTime(LocalDateTime localDateTime, TimeZone timeZone, Locale locale)
	{
		if (localDateTime == null) {
			return null;
		}
		Calendar lCalendar = Calendar.getInstance(timeZone, locale);
		lCalendar.set(Calendar.YEAR, localDateTime.getYear());
		lCalendar.set(Calendar.MONTH, localDateTime.getMonth().getValue() - 1);
		lCalendar.set(Calendar.DATE, localDateTime.getDayOfMonth());
		lCalendar.set(Calendar.HOUR_OF_DAY, localDateTime.getHour());
		lCalendar.set(Calendar.MINUTE, localDateTime.getMinute());
		lCalendar.set(Calendar.SECOND, localDateTime.getSecond());
		lCalendar.set(Calendar.MILLISECOND, localDateTime.getNano() / 1000000);
		return lCalendar;
	}
	
	/**
	 * 
	 * @param localTime
	 * @return
	 */
	public static Calendar createCalendarFromLocalTime(LocalTime localTime, TimeZone timeZone, Locale locale)
	{
		if (localTime == null) {
			return null;
		}
		Calendar lCalendar = Calendar.getInstance(timeZone, locale);
		lCalendar.set(Calendar.HOUR_OF_DAY, localTime.getHour());
		lCalendar.set(Calendar.MINUTE, localTime.getMinute());
		lCalendar.set(Calendar.SECOND, localTime.getSecond());
		lCalendar.set(Calendar.MILLISECOND, localTime.getNano() / 1000000);
		return lCalendar;
	}
	
	/**
	 * 
	 * @param calendar
	 * @return
	 */
	public static LocalDate createLocalDateFromCalendar(Calendar calendar)
	{
		if (calendar == null) {
			return null;
		}
		LocalDate lLocalDate = LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE));
		return lLocalDate;
	}
	
	/**
	 * 
	 * @param calendar
	 * @return
	 */
	public static ZonedDateTime createZonedDateTimeFromCalendar(Calendar calendar)
	{
		if (calendar == null) {
			return null;		
		}
		Instant instant = Instant.ofEpochMilli(calendar.getTimeInMillis());
		ZoneId zone = toZoneId(calendar.getTimeZone());
		return ZonedDateTime.ofInstant(instant, zone);
	}
	
	/**
	 * 
	 * @param calendar
	 * @return
	 */
	public static LocalDateTime createLocalDateTimeFromCalendar(Calendar calendar)
	{
		if (calendar == null) {
			return null;
		}
		LocalDateTime lLocalDateTime = LocalDateTime.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND) * 1000000);
		return lLocalDateTime;
	}
	
	/**
	 * 
	 * @param calendar
	 * @return
	 */
	public static LocalTime createLocalTimeFromCalendar(Calendar calendar)
	{
		if (calendar == null) {
			return null;
		}
		LocalTime lLocalTime = LocalTime.of(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND) * 1000000);
		return lLocalTime;
	}
	
	/*
	 *
	 */
	public static Date createDateFromLocalDate(LocalDate localDate) {
		if (localDate == null) {
			return null;
		}
		Instant lInstant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
		Date lDate = Date.from(lInstant);
		return lDate;
	}
	
	/**
	 * 
	 */
	public static LocalDate createLocaleDateFromDate(Date date) {
		if (date == null) {
			return null;
		}
		LocalDate lLocalDate = LocalDateTime.ofInstant( date.toInstant(), ZoneId.systemDefault() ).toLocalDate();
		return lLocalDate;
	}
	
	/*
	 *
	 */
	public static Date createDateFromLocalDateTime(LocalDateTime localDateTime) {
		if (localDateTime == null) {
			return null;
		}
		Instant lInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
		Date lDate = Date.from(lInstant);
		return lDate;
	}
	
	/**
	 * 
	 */
	public static LocalDateTime createLocaleDateTimeFromDate(Date date) {
		if (date == null) {
			return null;
		}
		// This gives strange results, for example: Sun Jan 01 02:02:02 CET 1111 -> 1111-01-08T01:55:30
		// LocalDateTime lLocalDateTime = LocalDateTime.ofInstant( date.toInstant(), ZoneId.systemDefault() );
		LocalDateTime lLocalDateTime = LocalDateTime.of(1900 + date.getYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
		return lLocalDateTime;
	}
	
	/**
	 * 
	 */
	public static LocalTime createLocaleTimeFromDate(Date date) {
		if (date == null) {
			return null;
		}
		LocalTime lLocalTime = LocalTime.of( date.getHours(), date.getMinutes(), date.getSeconds(), 0 );
		return lLocalTime;
	}

	/*
	 *
	 */
	public static Date createDateFromLocalTime(LocalTime localTime) {
		if (localTime == null) {
			return null;
		}
		Date lDate = createDateFromLocalDateTime( localTime.atDate(LocalDate.now()) );
		return lDate;
	}
	

	/**
	 * 
	 * @param calendarProperty
	 * @param localDateProperty
	 * @param localeProperty 
	 */
	static public void syncLocalDate(ObjectProperty calendarProperty, ObjectProperty localDateProperty, ObjectProperty localeProperty)
	{
		// initial
		calendarProperty.set(localDateProperty.get() == null ? null : createCalendarFromLocalDate(localDateProperty.get(), TimeZone.getDefault(), localeProperty.get()));
		
		// forward changes from calendar
		calendarProperty.addListener( (ObservableValue observableValue, Calendar oldValue, Calendar newValue) -> {
			localDateProperty.set(createLocalDateFromCalendar(newValue)); 
		});
		
		// forward changes to calendar
		localDateProperty.addListener( (ObservableValue observableValue, LocalDate oldValue, LocalDate newValue) -> {
			calendarProperty.set(newValue == null ? null : createCalendarFromLocalDate(newValue, TimeZone.getDefault(), localeProperty.get()));
		});
	}

	/**
	 * 
	 * @param calendarProperty
	 * @param localDateTimeProperty
	 * @param localeProperty 
	 */
	static public void syncLocalDateTime(ObjectProperty calendarProperty, ObjectProperty localDateTimeProperty, ObjectProperty localeProperty)
	{
		// initial
		calendarProperty.set(localDateTimeProperty.get() == null ? null : createCalendarFromLocalDateTime(localDateTimeProperty.get(), TimeZone.getDefault(), localeProperty.get()));
		
		// forward changes from calendar
		calendarProperty.addListener( (ObservableValue observableValue, Calendar oldValue, Calendar newValue) -> {
			localDateTimeProperty.set(createLocalDateTimeFromCalendar(newValue)); 
		});
		
		// forward changes to calendar
		localDateTimeProperty.addListener( (ObservableValue observableValue, LocalDateTime oldValue, LocalDateTime newValue) -> {
			calendarProperty.set(newValue == null ? null : createCalendarFromLocalDateTime(newValue, TimeZone.getDefault(), localeProperty.get()));
		});
	}


	/**
	 * 
	 * @param calendarProperty
	 * @param localTimeProperty
	 * @param localeProperty 
	 */
	static public void syncLocalTime(ObjectProperty calendarProperty, ObjectProperty localTimeProperty, ObjectProperty localeProperty)
	{
		// initial
		calendarProperty.set(localTimeProperty.get() == null ? null : createCalendarFromLocalTime(localTimeProperty.get(), TimeZone.getDefault(), localeProperty.get()));
		
		// forward changes from calendar
		calendarProperty.addListener( (ObservableValue observableValue, Calendar oldValue, Calendar newValue) -> {
			localTimeProperty.set(createLocalTimeFromCalendar(newValue)); 
		});
		
		// forward changes to calendar
		localTimeProperty.addListener( (ObservableValue observableValue, LocalTime oldValue, LocalTime newValue) -> {
			calendarProperty.set(newValue == null ? null : createCalendarFromLocalTime(newValue, TimeZone.getDefault(), localeProperty.get()));
		});
	}
	
	/**
	 * 
	 * @param calendars
	 * @param localDates
	 * @param localeProperty 
	 */
	static public void syncLocalDates(ObservableList calendars, ObservableList localDates, ObjectProperty localeProperty)
	{
		// initial values
		for (LocalDate lLocalDate : localDates) {
			Calendar lCalendar = createCalendarFromLocalDate(lLocalDate, TimeZone.getDefault(), localeProperty.get());
			calendars.add(lCalendar);
		}
		
		// forward changes from calendar
		calendars.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (Calendar lCalendar : change.getRemoved())
				{
					LocalDate lLocalDate = createLocalDateFromCalendar(lCalendar);
					if (localDates.contains(lLocalDate)) {
						localDates.remove(lLocalDate);
					}				
				}
				for (Calendar lCalendar : change.getAddedSubList()) 
				{
					LocalDate lLocalDate = createLocalDateFromCalendar(lCalendar);
					if (localDates.contains(lLocalDate) == false) {
						localDates.add(lLocalDate);
					}
				}
			}
		});
		
		// forward changes to calendar
		localDates.addListener( (ListChangeListener.Change change) -> {
			while (change.next()) {
				for (LocalDate lLocalDate : change.getRemoved()) {
					Calendar lCalendar = createCalendarFromLocalDate(lLocalDate, TimeZone.getDefault(), localeProperty.get());
					if (calendars.contains(lCalendar)) {
						calendars.remove(lCalendar);
					}
				}
				for (LocalDate lLocalDate : change.getAddedSubList()) {
					Calendar lCalendar = createCalendarFromLocalDate(lLocalDate, TimeZone.getDefault(), localeProperty.get());
					if (calendars.contains(lCalendar) == false) {
						calendars.add(lCalendar);
					}
				}
			}
		});
	}
	
	/**
	 * 
	 * @param calendars
	 * @param localDateTimes
	 * @param localeProperty 
	 */
	static public void syncLocalDateTimes(ObservableList calendars, ObservableList localDateTimes, ObjectProperty localeProperty)
	{
		// initial values
		for (LocalDateTime lLocalDateTime : localDateTimes) {
			Calendar lCalendar = createCalendarFromLocalDateTime(lLocalDateTime, TimeZone.getDefault(), localeProperty.get());
			calendars.add(lCalendar);
		}
		
		// forward changes from calendar
		calendars.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (Calendar lCalendar : change.getRemoved())
				{
					LocalDateTime lLocalDateTime = createLocalDateTimeFromCalendar(lCalendar);
					if (localDateTimes.contains(lLocalDateTime)) {
						localDateTimes.remove(lLocalDateTime);
					}				
				}
				for (Calendar lCalendar : change.getAddedSubList()) 
				{
					LocalDateTime lLocalDateTime = createLocalDateTimeFromCalendar(lCalendar);
					if (localDateTimes.contains(lLocalDateTime) == false) {
						localDateTimes.add(lLocalDateTime);
					}
				}
			}
		});
		
		// forward changes to calendar
		localDateTimes.addListener( (ListChangeListener.Change change) -> {
			while (change.next()) {
				for (LocalDateTime lLocalDateTime : change.getRemoved()) {
					Calendar lCalendar = createCalendarFromLocalDateTime(lLocalDateTime, TimeZone.getDefault(), localeProperty.get());
					if (calendars.contains(lCalendar)) {
						calendars.remove(lCalendar);
					}
				}
				for (LocalDateTime lLocalDateTime : change.getAddedSubList()) {
					Calendar lCalendar = createCalendarFromLocalDateTime(lLocalDateTime, TimeZone.getDefault(), localeProperty.get());
					if (calendars.contains(lCalendar) == false) {
						calendars.add(lCalendar);
					}
				}
			}
		});
	}

	// -------
	// DateTimeFormatterForDate
	
	static public void syncDateTimeFormatterForDate(ObjectProperty dateFormatProperty, ObjectProperty dateTimeFormatterProperty) {
		dateFormatProperty.set( dateTimeFormatterProperty.get() == null ? null : new DateTimeFormatterToDateFormatWrapper( dateTimeFormatterProperty.get() ));
		dateTimeFormatterProperty.addListener( (observable) -> {
			dateFormatProperty.set( new DateTimeFormatterToDateFormatWrapper( dateTimeFormatterProperty.get() ));
		});
	}
	
	static public void syncDateTimeFormattersForDate(ListProperty dateFormatsProperty, ListProperty dateTimeFormattersProperty) {
		final Map map = new WeakHashMap<>();
		
		// initial values
		for (DateTimeFormatter lDateTimeFormatter : dateTimeFormattersProperty) {
			DateTimeFormatterToDateFormatWrapper lDateTimeFormatterToDateFormatWrapper = new DateTimeFormatterToDateFormatWrapper( lDateTimeFormatter );
			map.put(lDateTimeFormatter, lDateTimeFormatterToDateFormatWrapper);
			dateFormatsProperty.add( lDateTimeFormatterToDateFormatWrapper );
		}
		
		// forward changes from localDate
		dateTimeFormattersProperty.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (DateTimeFormatter lDateTimeFormatter : change.getRemoved())
				{
					DateTimeFormatterToDateFormatWrapper lDateTimeFormatterToDateFormatWrapper = map.remove(lDateTimeFormatter);
					dateFormatsProperty.remove(lDateTimeFormatterToDateFormatWrapper);
				}
				for (DateTimeFormatter lDateTimeFormatter : change.getAddedSubList()) 
				{
					DateTimeFormatterToDateFormatWrapper lDateTimeFormatterToDateFormatWrapper = new DateTimeFormatterToDateFormatWrapper( lDateTimeFormatter );
					map.put(lDateTimeFormatter, lDateTimeFormatterToDateFormatWrapper);
					dateFormatsProperty.add(lDateTimeFormatterToDateFormatWrapper);
				}
			}
		});
	}

	/**
	 * 
	 */
	static class DateTimeFormatterToDateFormatWrapper extends DateFormat {

		public DateTimeFormatterToDateFormatWrapper(DateTimeFormatter dateTimeFormatter) {
			this.dateTimeFormatter = dateTimeFormatter;
		}
		final private DateTimeFormatter dateTimeFormatter;
		
		@Override
		public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
			LocalDate lLocalDate = createLocaleDateFromDate(date);
			String s = this.dateTimeFormatter.format( lLocalDate );
			toAppendTo.append(s);
			return toAppendTo;
		}

		@Override
		public Date parse(String source, ParsePosition pos) {
			LocalDate lLocalDate = LocalDate.parse(source, this.dateTimeFormatter);
			Date lDate = createDateFromLocalDate(lLocalDate);
			pos.setIndex(source.length()); // otherwise DateFormat will thrown an exception 
			return lDate;
		}
		
		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			return (this == obj);
		}
		
		public String toString() {
			return dateTimeFormatter.toString();
		}
	}

	// -------
	// DateTimeFormatterForDateTime
	
	static public void syncDateTimeFormatterForDateTime(ObjectProperty dateFormatProperty, ObjectProperty dateTimeFormatterProperty) {
		dateFormatProperty.set( dateTimeFormatterProperty.get() == null ? null : new DateTimeFormatterToDateTimeFormatWrapper( dateTimeFormatterProperty.get() ));
		dateTimeFormatterProperty.addListener( (observable) -> {
			dateFormatProperty.set( new DateTimeFormatterToDateTimeFormatWrapper( dateTimeFormatterProperty.get() ));
		});
	}
	
	static public void syncDateTimeFormattersForDateTime(ListProperty dateFormatsProperty, ListProperty dateTimeFormattersProperty) {
		final Map map = new WeakHashMap<>();
		
		// initial values
		for (DateTimeFormatter lDateTimeFormatter : dateTimeFormattersProperty) {
			DateTimeFormatterToDateTimeFormatWrapper lDateTimeFormatterToDateTimeFormatWrapper = new DateTimeFormatterToDateTimeFormatWrapper( lDateTimeFormatter );
			map.put(lDateTimeFormatter, lDateTimeFormatterToDateTimeFormatWrapper);
			dateFormatsProperty.add( lDateTimeFormatterToDateTimeFormatWrapper );
		}
		
		// forward changes from localDate
		dateTimeFormattersProperty.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (DateTimeFormatter lDateTimeFormatter : change.getRemoved())
				{
					DateTimeFormatterToDateTimeFormatWrapper lDateTimeFormatterToDateTimeFormatWrapper = map.remove(lDateTimeFormatter);
					dateFormatsProperty.remove(lDateTimeFormatterToDateTimeFormatWrapper);
				}
				for (DateTimeFormatter lDateTimeFormatter : change.getAddedSubList()) 
				{
					DateTimeFormatterToDateTimeFormatWrapper lDateTimeFormatterToDateTimeFormatWrapper = new DateTimeFormatterToDateTimeFormatWrapper( lDateTimeFormatter );
					map.put(lDateTimeFormatter, lDateTimeFormatterToDateTimeFormatWrapper);
					dateFormatsProperty.add(lDateTimeFormatterToDateTimeFormatWrapper);
				}
			}
		});
	}

	/**
	 * 
	 */
	static class DateTimeFormatterToDateTimeFormatWrapper extends DateFormat {

		public DateTimeFormatterToDateTimeFormatWrapper(DateTimeFormatter dateTimeFormatter) {
			this.dateTimeFormatter = dateTimeFormatter;
		}
		final private DateTimeFormatter dateTimeFormatter;
		
		@Override
		public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
			LocalDateTime lLocalDateTime = createLocaleDateTimeFromDate(date);
			String s = this.dateTimeFormatter.format( lLocalDateTime );
			toAppendTo.append(s);
			return toAppendTo;
		}

		@Override
		public Date parse(String source, ParsePosition pos) {
			LocalDateTime lLocalDateTime = LocalDateTime.parse(source, this.dateTimeFormatter);
			Date lDate = createDateFromLocalDateTime(lLocalDateTime);
			pos.setIndex(source.length()); // otherwise DateFormat will thrown an exception 
			return lDate;
		}
		
		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			return (this == obj);
		}
		
		public String toString() {
			return dateTimeFormatter.toString();
		}
	}


	// -------
	// DateTimeFormatterForTime
	
	static public void syncDateTimeFormatterForTime(ObjectProperty dateFormatProperty, ObjectProperty dateTimeFormatterProperty) {
		dateFormatProperty.set( dateTimeFormatterProperty.get() == null ? null : new DateTimeFormatterToTimeFormatWrapper( dateTimeFormatterProperty.get() ));
		dateTimeFormatterProperty.addListener( (observable) -> {
			dateFormatProperty.set( new DateTimeFormatterToTimeFormatWrapper( dateTimeFormatterProperty.get() ));
		});
	}
	
	static public void syncDateTimeFormattersForTime(ListProperty dateFormatsProperty, ListProperty dateTimeFormattersProperty) {
		final Map map = new WeakHashMap<>();
		
		// initial values
		for (DateTimeFormatter lDateTimeFormatter : dateTimeFormattersProperty) {
			DateTimeFormatterToTimeFormatWrapper lDateTimeFormatterToTimeFormatWrapper = new DateTimeFormatterToTimeFormatWrapper( lDateTimeFormatter );
			map.put(lDateTimeFormatter, lDateTimeFormatterToTimeFormatWrapper);
			dateFormatsProperty.add( lDateTimeFormatterToTimeFormatWrapper );
		}
		
		// forward changes from localDate
		dateTimeFormattersProperty.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (DateTimeFormatter lDateTimeFormatter : change.getRemoved())
				{
					DateTimeFormatterToTimeFormatWrapper lDateTimeFormatterToTimeFormatWrapper = map.remove(lDateTimeFormatter);
					dateFormatsProperty.remove(lDateTimeFormatterToTimeFormatWrapper);
				}
				for (DateTimeFormatter lDateTimeFormatter : change.getAddedSubList()) 
				{
					DateTimeFormatterToTimeFormatWrapper lDateTimeFormatterToTimeFormatWrapper = new DateTimeFormatterToTimeFormatWrapper( lDateTimeFormatter );
					map.put(lDateTimeFormatter, lDateTimeFormatterToTimeFormatWrapper);
					dateFormatsProperty.add(lDateTimeFormatterToTimeFormatWrapper);
				}
			}
		});
	}

	/**
	 * 
	 */
	static class DateTimeFormatterToTimeFormatWrapper extends DateFormat {

		public DateTimeFormatterToTimeFormatWrapper(DateTimeFormatter dateTimeFormatter) {
			this.dateTimeFormatter = dateTimeFormatter;
		}
		final private DateTimeFormatter dateTimeFormatter;
		
		@Override
		public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
			LocalTime lLocalTime = createLocaleTimeFromDate(date);
			String s = this.dateTimeFormatter.format( lLocalTime );
			toAppendTo.append(s);
			return toAppendTo;
		}

		@Override
		public Date parse(String source, ParsePosition pos) {
			LocalTime lLocalTime = LocalTime.parse(source, this.dateTimeFormatter);
			Date lDate = createDateFromLocalTime(lLocalTime);
			pos.setIndex(source.length()); // otherwise DateFormat will thrown an exception 
			return lDate;
		}
		
		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			return (this == obj);
		}
		
		public String toString() {
			return dateTimeFormatter.toString();
		}
	}

	static public void sync(ObservableList calendars, ObservableList localDateTimes)
	{
		// initial values
                calendars.addAll(localDateTimes);
		
		// forward changes from calendar
		calendars.addListener( (ListChangeListener.Change change) -> {
			while (change.next())
			{
				for (Calendar lCalendar : change.getRemoved())
				{
					if (localDateTimes.contains(lCalendar)) {
						localDateTimes.remove(lCalendar);
					}				
				}
				for (Calendar lCalendar : change.getAddedSubList()) 
				{
					if (localDateTimes.contains(lCalendar) == false) {
						localDateTimes.add(lCalendar);
					}
				}
			}
		});
		
		// forward changes to calendar
		localDateTimes.addListener( (ListChangeListener.Change change) -> {
			while (change.next()) {
				for (Calendar lCalendar : change.getRemoved()) {
					if (calendars.contains(lCalendar)) {
						calendars.remove(lCalendar);
					}
				}
				for (Calendar lCalendar : change.getAddedSubList()) {
					if (calendars.contains(lCalendar) == false) {
						calendars.add(lCalendar);
					}
				}
			}
		});
	}

	/**
	 * 
	 */
	static public String quickFormatCalendar(Calendar value)
	{
		if (value == null) return "";
		SimpleDateFormat lSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		return lSimpleDateFormat.format(value.getTime());
	}

	/**
	 * 
	 */
	static public String quickFormatCalendar(List value)
	{
		if (value == null) return "null";
		String s = value.size() + "x [";
		for (Calendar lCalendar : value)
		{
			if (s.endsWith("[") == false) s += ",";
			s += quickFormatCalendar(lCalendar);
		}
		s += "]";
		return s;
	}
	

	public static ZoneId toZoneId(TimeZone timeZone) {
		return ZoneId.of(timeZone.getID(), ZoneId.SHORT_IDS);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy