Назначение класса - PullRequest
       4

Назначение класса

0 голосов
/ 21 ноября 2018

Я пытаюсь создать метод, который бы добавлял встречу к списку встреч с архивами.Этот метод будет проверять дату, чтобы увидеть, равен ли пользовательский ввод SimpleDateFormat в моем коде, startTime и endTime встречи, и посмотреть, будет ли она в будущем или нет.

Я пытался использовать java Date api, чтобы проверить это, но когда я пытаюсь расширить класс, чтобы получить доступ к атрибутам, это всегда вызывает ошибку во время компиляции.Итак, в целом мой вопрос заключается в том, как лучше всего сравнить объект типа назначения с объектом типа дата?Я пытаюсь использовать аксессоры для getDate (), startTime и endTime, но я не могу их получить.

public AppointmentDate(String appString)
{
    // 1) split ithe string into Date/from/to
    // 2) consturct the Date object for the appDate
    // 3) consturct the Date object for the startTime
    // 4) consturct the Date object for the endTime

    String[] appDetails = appString.split(",");

    if(appDetails.length == 2)
    {
        try {
            SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
            this.appDate = df.parse(appDetails[0]);
            DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy,mm:HH");
            String dFormat = appDetails[0] + "," + appDetails[1];
            this.startTime = formatter.parse(dFormat);
            dFormat = appDetails[0] + "," + appDetails[2];
            this.endTime = formatter.parse(dFormat);
        }
        catch (Exception ex)
        {

        }
    }

    else 
    {
        System.out.print("User Date is Invalid");
    }
}
public void setStartTime(Date startTime) 
{
    this.startTime = startTime;
}

public Date getStartTime()
{
    return startTime;
}

public void setEndTime(Date endTime) 
{
    this.endTime = endTime;
}

public Date getEndTime()
{
    return endTime;
}

public void setAppdate(Date appDate) 
{
    this.appDate = appDate;
}

public Date getAppDate()
{
    return appDate;
}


public void add(Appointment a) 
{
    if (a.equals(a.getDate()))
    {
        if(a.getStartTime() < a.getEndTime())
        {

        }
    }
    else
    {
        System.out.print("");
    }

}

1 Ответ

0 голосов
/ 21 ноября 2018

Статический блок (почти)

Ваш код для занятий в классе находится не в том месте.Вы застряли в верхней части класса, что не является синтаксически правильным.Мы можем выполнить код сверху, как статический блок , но его нужно пометить static { … }.Статический блок обычно не используется в моем опыте.И, конечно же, это не то место, что вы там делаете.

main метод

Вместо этого вы должны использовать a main метод .Эта не ООП маленькая штучка - хитрость, взлом, чтобы решить загадку курица или яйцо , чтобы вывести нас из неиспользуемого приложения к нашей ООП-идеенебес с кучей объектов, плавающих вокруг и передавая сообщения друг другу.

При первом изучении Java, не пытайтесь понять весь синтаксис и цель метода main.Просто примите это как необходимое зло для запуска приложения, это всего лишь точка входа в приложение.Сосредоточьтесь на изучении концепций и практик ООП.Позже метод и синтаксис main станут более понятными.

Средства доступа

Вот упрощенная перезапись вашего примера кода.Мы просто используем LocalDate для простоты, достаточно, чтобы показать (а) метод main и (б) методы получения / установки методы доступа .

package com.basilbourque.example;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class AppointmentDate {
    private LocalDate localDate;

    // Constructor
    public AppointmentDate ( LocalDate localDate ) {
        this.localDate = localDate;
    }

    public LocalDate getLocalDate ( ) {
        return localDate;
    }

    public void setLocalDate ( LocalDate localDate ) {
        this.localDate = localDate;
    }

    @Override
    public String toString ( ) {
        return "AppointmentDate{ " +
                "localDate=" + localDate +
                " }";
    }

    // Not really a part of this class. A `main` method is just a hack to get our app launched.
    public static void main ( String[] args ) {
        String input = "23/01/2018";
        DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
        LocalDate ld = LocalDate.parse( input , f );
        AppointmentDate ad = new AppointmentDate( ld );
        ad.setLocalDate( ld.plusWeeks( 1 ) );
        LocalDate newValue = ad.getLocalDate();
        System.out.println( newValue.toString() );  // Generate text representing the value of this `LocalDate` object in standard ISO 8601 format.

        List < AppointmentDate > list = new ArrayList <>( 3 );
        list.add( ad );
        list.add( new AppointmentDate( LocalDate.parse( "2018-02-13" ) ) );
        list.add( new AppointmentDate( LocalDate.parse( "2018-12-21" ) ) );
        System.out.println( list );
    }
}

2018-01-30

[AppointmentDate {localDate = 2018-01-30}, AppointmentDate {localDate = 2018-02-13}, AppointmentDate {localDate = 2018-12-21}]

java.time

Вы используете ужасные старые классы даты и времени, которые были вытеснены несколько лет назад классами java.time .Никогда не используйте Date, Calendar, SimpleDateFormat и т. Д.

Назначения сложны

Хотя отслеживание встреч может показаться интуитивно простым, на самом деле вы работаете над очень сложным предметом.

Основная проблема заключается в том, что политики во всем мире любят пересматривать часовой пояс под своей юрисдикцией.Они делают это довольно часто.Они делают это как в относительно спокойное время, так и во времена смуты.

США и Канада несколько раз меняли свои смещения за последние десятилетия.За последние несколько лет Турция и Россия неоднократно меняли мнение о том, включать или выключать летнее время.

А политики меняют свои часовые пояса с очень небольшим предварительным уведомлением.И уведомление, кажется, становится все короче, несмотря на растущее беспокойство, которое это вызывает в все более компьютеризированных обществах.Только в прошлом месяце Марокко объявило , что их страна останется на постоянном летнем времени (DST), отменив в пятницу переход на летнее время, запланированный на это воскресенье, оставив предупреждение о 0 рабочих днях - что за беспорядок для ИТ-персонала.В мае этого года Северная Корея переставила свои часы на полчаса, чтобы синхронизировать их с Южной Кореей, с очевидным немедленным эффектом (никакого предварительного уведомления вообще).

Эти частые и непредсказуемые изменения означают, что мы не можем ответственно отслеживать будущие встречи как моменты, как конкретные моменты на временной шкале.Когда мы говорим что-то вроде «3 часа дня 23 января», мы обычно имеем в виду 3 часа дня после того, как политики могли внести свои изменения в часы.

Таким образом, мы должны хранить будущие встречи как дату и время суток без часового пояса или смещения от UTC.Затем при расчете календаря мы должны динамически применять правила для намеченного часового пояса, определенного в данный момент в этот день.Если мы выполним это динамическое определение момента сегодня и снова через три дня, если политики объявили об изменении определения часового пояса и смогли ли мы обновить наши данные tzdataфайлы в наших операционных системах, движках баз данных, виртуальных машинах Java и различных библиотеках, тогда мы прибудем в другой момент времени .

LocalDateTime

Local… типах Java специально отсутствует понятие часового пояса или смещения от UTC.Таким образом, они не могут представлять момент.Поэтому мы никогда не используем их для точного определения фактических событий, которые произошли в прошлом.Но эти типы - то, что нам нужно для будущих встреч.

Класс LocalDateTime представляет дату с временем дня без какой-либо зоны / смещения.

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 0 ) ;  // 3 PM in 24-hour time.
LocalDateTime ldt= LocalDateTime.of( ld , lt ) ;

ZonedDateTime

При вычислении календаря, когда нам нужен определенный момент, мы применяем часовой пояс (ZoneId), чтобы получить объект ZonedDateTime.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  // Determine a moment, a specific point on the timeline.

Instant

Мы можем просмотреть тот же момент в UTC, извлекая Instant.

Instant instant = zdt.toInstant() ;   // Adjust to UTC.

Duration

Назначениякак правило, лучше всего хранить в качестве отправной точки плюс продолжительность.Нет необходимости хранить точку остановки, так как она может быть рассчитана.

Duration d = Duration.ofHours( 1 ) ;  // A one-hour appointment.

Хотя мы часто хотим настроить часовой пояс для представления пользователю, как правило, за кадром, лучше всего отслеживать моменты в UTC.Таким образом, точки начала и окончания встречи, рассчитанные как моменты, должны быть выполнены в виде пары Instant объектов.

Instant start = ldt.atZone( z ).toInstant() ;
Instant stop = start.plus( d ) ;

Interval

Мы можем использовать класс для представления этогопара Instant объектов, Interval.

Этот класс находится в библиотеке ThreeTen-Extra , которой руководит тот же человек, что и Joda-Time, JSR 310 и java.time проекты, Стивен Коулборн.

Этот класс имеет очень удобные методы для сравнения, такие как abuts, overlaps, contains и так далее.Вероятно, вы захотите использовать эти методы в приложении планирования.

Appointment.java

Соберите все это вместе, и мы получим такой класс:

package com.basilbourque.example;

import org.threeten.extra.Interval;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Appointment {
    private LocalDateTime start;
    private Duration duration;

    // Constructor.
    public Appointment ( LocalDateTime start , Duration duration ) {
        this.start = start;
        this.duration = duration;
    }

    // Might add some getter/setter methods in here.

    // Dynamically determine the start and stop points of this appointment, given today’s definition of the intended time zone.
    public Interval toInterval ( ZoneId zoneId ) {
        ZonedDateTime zdtStart = this.start.atZone( zoneId );
        Interval interval = Interval.of( zdtStart.toInstant() , this.duration );
        return interval;
    }

}

Когда вы генерируете Interval, вызывая ваш toInterval методВы можете захотеть отдельные моменты запуска и остановки.

Instant start = interval.getStart() ;
Instant stop = interval.getEnd() ;

Эти два объекта Instant находятся в UTC по определению.Если вы хотите увидеть их сквозь призму настенных часов, используемых людьми определенного региона, примените ZoneId, чтобы получить ZonedDateTime объект.

ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtStart = start.atZone( z ) ;  // Adjust from UTC to some time zone. Same moment, same point on the timeline, different wall-clock time.
ZonedDateTime zdtStop = stop.atZone( z ) ;

Future

Вы спрашивали о проверке, чтобы увидеть, будет ли это назначение в будущем.Опять же, нам нужен часовой пояс, чтобы правильно ответить, чем.Часовые пояса по всему миру в настоящее время охватывают диапазон от 26 до 27 часов.Таким образом, в течение многих часов текущего момента мы не можем определить, является ли LocalDateTime будущим или прошедшим, без учета часового пояса.

Итак, давайте добавим метод тестирования для будущего, который требует времениzone.

// Dynamically determine if this appointment will be in the future for some specific time zone.
public Boolean isFuture ( ZoneId zoneId ) {
    Objects.requireNonNull( zoneId , "Must pass a time zone to determine if an appointment is in the future. Message # e1c64bc1-9a44-4d15-b20d-e68414fb5ab5.");
    ZonedDateTime zdtStart = this.start.atZone( zoneId );
    ZonedDateTime zdtNow = ZonedDateTime.now( zoneId );
    boolean isInTheFuture = zdtNow.isBefore( zdtStart );
    return isInTheFuture ;
}

Моменты пуска / останова

Продолжая ту же тему для динамически определяемых моментов, давайте добавим несколько методов для возврата начального момента (включительно) и момента остановки (исключая).Как уже говорилось выше, для этого требуется передать часовой пояс.

Вызывающий программист может выполнить эту работу самостоятельно.Но я подозреваю, что это может быть достаточно часто, чтобы оправдать добавление этих методов для удобства.

// Get start moment for a particular time zone.
public ZonedDateTime toStartMoment ( ZoneId zoneId ) {
    ZonedDateTime zdt = this.toInterval( zoneId ).getStart().atZone( zoneId );
    return zdt;
}

// Get stop moment for a particular time zone.
public ZonedDateTime toStopMoment ( ZoneId zoneId ) {
    ZonedDateTime zdt = this.toInterval( zoneId ).getEnd().atZone( zoneId );
    return zdt;
}

Обратите внимание, что я не назвал эти методы с get….Методы доступа, методы получения и установки, по соглашению, подразумевают доступ к простому свойству, хранящемуся внутри объекта.Но здесь мы не храним объекты ZonedDateTime.Они определяются динамически, поэтому использование метода get… может вводить в заблуждение.Вместо этого я пытаюсь следовать соглашениям об именах, изложенным в java.time проекте .

неизменяемых объектов

Еще один урок, из которого можно извлечь уроки java.time - это шаблон неизменных объектов .

Некоторые виды классов могут быть созданы только для чтения, но не изменены.Классы java.time , безусловно, соответствуют требованиям.Принимая во внимание, что, например, счет-фактура, как ожидается, будет «видоизменяться» (изменяться), интуитивно, как программист, я не ожидаю, что дата в счете-фактуре изменится, если я явно не заменю дату новым объектом.Поэтому я хочу, чтобы счет был изменяемым объектом, но я хочу, чтобы LocalDate объект, сохраненный в этом счете, был неизменным .

Я подозреваю, что наш Appointmentкласс также может быть лучше всего разработан как неизменный.Таким образом, у нас нет методов setter.Чтобы эффективно изменить встречу в приложении планирования, создайте новый объект Appointment на основе некоторых значений существующего объекта Appointment.Обратите внимание на классы java.time , как это делается с помощью различных методов with, где методы возвращают новый объект на основе значений оригинала, но с некоторыми изменениями.

Appointment.javaверсия 2

Давайте соединим все это в один пример класса.

И давайте добавим метод main для изучения этого класса.Сначала мы создаем одну встречу и смотрим на ее динамически определяемые моменты в UTC.Во-вторых, мы собираем Appointment объектов в коллекции.

Мы добавили переопределение метода toString, чтобы сообщать о состоянии объекта.

package com.basilbourque.example;

import org.threeten.extra.Interval;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

// An example class to show date-time handling for future appointments.
// Not necessarily ready for production use. Use at your own risk.
// Methods named according to the java.time naming conventions:
// https://docs.oracle.com/javase/tutorial/datetime/overview/naming.html
public class Appointment {
    private LocalDateTime start;
    private Duration duration;

    // Constructor.
    public Appointment ( LocalDateTime start , Duration duration ) {
        this.start = start;
        this.duration = duration;
    }

    // Dynamically determine the start and stop points of this appointment, given today’s definition of the intended time zone.
    public Interval toInterval ( ZoneId zoneId ) {
        Objects.requireNonNull( zoneId , "Must pass a time zone to get the start/stop interval of an appointment. Message # bbf021e6-baa7-468d-83ad-cf73acb6702e." );
        ZonedDateTime zdtStart = this.start.atZone( zoneId );
        Interval interval = Interval.of( zdtStart.toInstant() , this.duration );
        return interval;
    }

    // Get start moment for a particular time zone.
    public ZonedDateTime toStartMoment ( ZoneId zoneId ) {
        ZonedDateTime zdt = this.toInterval( zoneId ).getStart().atZone( zoneId );
        return zdt;
    }

    // Get stop moment for a particular time zone.
    public ZonedDateTime toStopMoment ( ZoneId zoneId ) {
        ZonedDateTime zdt = this.toInterval( zoneId ).getEnd().atZone( zoneId );
        return zdt;
    }

    // Dynamically determine if this appointment will be in the future for some specific time zone.
    public Boolean isFuture ( ZoneId zoneId ) {
        Objects.requireNonNull( zoneId , "Must pass a time zone to determine if an appointment is in the future. Message # e1c64bc1-9a44-4d15-b20d-e68414fb5ab5." );
        ZonedDateTime zdtStart = this.start.atZone( zoneId );
        ZonedDateTime zdtNow = ZonedDateTime.now( zoneId );
        boolean isInTheFuture = zdtNow.isBefore( zdtStart );
        return isInTheFuture;
    }

    // -----------|  Object overrides  |---------------------------
    @Override
    public String toString ( ) {
        return "Appointment{ " +
                "start=" + start +
                " | duration=" + duration +
                " }";
    }

    // -----------|  main  |-------------
    public static void main ( String[] args ) {
        // See if a new appointment is in the future.
        Appointment a = new Appointment( LocalDateTime.of( 2018 , 12 , 25 , 0 , 0 , 0 , 0 ) , Duration.ofHours( 2 ) );  
        ZoneId z = ZoneId.of( "America/Montreal" );
        System.out.println( "For time zone: " + z + ", appointment interval is: " + a.toInterval( z ) );
        System.out.println( "Start: " + a.toStartMoment( z ) );
        System.out.println( "Stop: " + a.toStopMoment( z ) );

        Boolean isFuture = a.isFuture( z );
        System.out.println( a.toString() + " is future t/f: " + isFuture );

        // Collect some appointments.
        List < Appointment > list = new ArrayList <>( 3 );
        list.add( a );
        list.add( new Appointment( LocalDateTime.of( 2018 , 12 , 13 , 15 , 0 , 0 , 0 ) , Duration.ofMinutes( 90 ) ) );
        list.add( new Appointment( LocalDateTime.of( 2018 , 12 , 30 , 16 , 0 , 0 , 0 ) , Duration.ofHours( 1 ) ) );
        System.out.println( list );
    }

}

При запуске.

Для часового пояса: Америка / Монреаль, интервал назначения: 2018-12-25T05: 00: 00Z / 2018-12-25T07: 00: 00Z

Начало: 2018-12-25T00: 00-05: 00 [Америка / Монреаль]

Остановка: 2018-12-25T02: 00-05: 00 [Америка / Монреаль]

Назначение {начало = 2018-12-25T00: 00 |длительность = PT2H} - будущее t / f: true

[Назначение {начало = 2018-12-25T00: 00 |длительность = PT2H}, Назначение {начало = 2018-12-13T15: 00 |продолжительность = PT1H30M}, Назначение {начало = 2018-12-30T16: 00 |duration = PT1H}]


О java.time

Рамка java.time встроен в Java 8 и позже.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с связанной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесены в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии комплектов Android для реализации java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...