Ява получить день недели не точно - PullRequest
0 голосов
/ 10 января 2011

Я пытаюсь определить, какой день недели является первым днем ​​месяца, но по какой-то причине он не возвращает мне правильный день недели.

Вот мой код ниже:

CalendarMonth[] months = CalendarUtils.constructMonthViewArray(new GregorianCalendar());


    public static CalendarMonth[] constructMonthViewArray(Calendar cal) {
        CalendarMonth[] months = new CalendarMonth[CALENDAR_GRID_SIZE];


        int year = cal.get(cal.YEAR);
        int month = cal.get(cal.MONTH);;
        // calculate how many days in the month
        int numOfDays = getNumOfDaysInMonth(cal);
        // calculate what day(mon-sunday) is the 1st of the month
        int firstDayOfMonth = getFirstDayOfMonth(cal);



private static int getFirstDayOfMonth(Calendar cal) {
        int firstDay = cal.get(Calendar.DAY_OF_WEEK);

        Log.d(TAG, "");

        // decrement it because our array deals with values 0-6(indexes)
        firstDay--;


        if (firstDay == 0) {
            firstDay = 6;
        } else {
            // decrement again so that the days start from 0.
            firstDay--;
        }
        return firstDay;
    }

Строка из "int firstDay = cal.get (Calendar.DAY_OF_WEEK);"не может дать мне правильный день недели и возвращает значение 2 для получения 1-го числа этого месяца (январь 2011 года), когда первое число было в субботу (7).

Я пропустилчто-то?Я отладил и проверил, в каком месяце, году и дате установлена ​​переменная cal, и она действительно указала сегодняшнюю дату как исправленную, но когда я получаю день недели, он не получает значение 7.

Ответы [ 3 ]

11 голосов
/ 10 января 2011

Я не могу воспроизвести проблему, которую вы видите.Как говорит Майкл, есть много кода, который вы нам не показали, но Calendar.getDayOfWeek определенно работает:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Calendar calendar = new GregorianCalendar();
        calendar.set(2011, 0, 1); // 0 = January
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK)); // Prints 7
    }
}

Возможно, вы забыли, что месяцы основаны на 0 в java.util.Calendar?

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

Тот факт, что вы уменьшаете firstDay в два раза в течениеgetFirstDayOfMonth кажется несколько странным, а также тот факт, что он на самом деле не отражает название метода (как упоминал Майкл).

Наконец, моя постоянная рекомендация по обработке даты / времени в Java: если выможете возможно использовать Joda Time вместо java.util.Calendar, сделайте это.Это намного лучше API.

0 голосов
/ 17 декабря 2015

tl; dr

Преобразование из ужасных унаследованных классов (Calendar, GregorianCalendar и т. Д.) В современные java.time классы (ZonedDateTime, LocalDate,так далее.).Затем получите объект для дня недели и попросите его автоматически локализовать имя этого дня недели.

(GregorianCalendar) myJavaUtilCalendar   // Cast your `Calendar` to `GregorianCalendar` assuming it actually is one.
.toZonedDateTime()                       // Convert from legacy class to modern class.
.toLocalDate()                           // Extract date-only object, without time-of-day and without time zone.
.with(                                   // Adjust to another date by calling `TemporalAdjuster` implementation such as are found in `TemporalAdjusters` class.
    TemporalAdjusters.firstDayOfMonth()  // Adjust to the first day of the month.
)                                        // Returns another `LocalDate` object, for the first of the month.
.getDayOfWeek()                          // Obtain a `DayOfWeek` enum object, one of seven pre-defined objects representing each day of the week.
.getDisplayName(                         // Automatically localize.
    TextStyle.FULL ,                     // Specify how long or abbreviated.
    Locale.CANADA_FRENCH                 // Or `Locale.US` etc. to specify the human language and cultural norms to use in localizing.
)                                        // Returns text in a `String` such as “Monday” or “lundi”.

java.time

The java.util.Calendar /.Дата и связанные с ней классы - запутанный беспорядок, поскольку вы выучили трудный путь.

Современный подход использует java.time классы.

Преобразование

Если вы начинаете с объекта java.util.Calendar, преобразуйте его в java.time.

Instant - это момент на временной шкале в UTC .

Instant instant = myJavaUtilCalendarObject.toInstant();

Применить часовой пояс, чтобы получить дату, чтобы получить день-of-week.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Обратите внимание, что часовой пояс имеет решающее значение при определении даты (и, следовательно, дня недели).«Сегодня» - это не одна и та же дата во всем мире одновременно.Например, в Париже наступает новый день раньше, чем в Монреале.

Первый день месяца

Давайте перейдем к первому числу месяца, позвонив по номеру withDayOfMonth.

ZonedDateTime zdtFirstOfMonth = zdt.withDayOfMonth(1);

Обратите внимание, что перемещение даты-времени в первое число месяца имеет проблемы.Такие аномалии, как летнее время (DST), могут иметь неожиданный эффект.Прочитайте документ, чтобы понять поведение.

DayOfWeek

Для дня недели используйте хорошо названное DayOfWeek enum .

DayOfWeek dayOfWeek = zdtFirstOfMonth.getDayOfWeek();

Я предлагаю передавать экземпляры этого перечисления, а не магическое число , как 2, 7 и т. Д. Но если вы настаиваете, вы можете извлечь целое число.

int dayOfWeekNumber = dayOfWeek.getValue();

Чтобы получить строку с именем дня недели, пусть java.time сгенерирует локализованную строку с помощью метода getDisplayName.

String output = dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );  // Or Locale.ENGLISH

О 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 и еще .

0 голосов
/ 10 января 2011

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

Следует помнить одну вещь: то, что считается первым днем ​​недели, зависит от локали, согласно getFirstDayOfWeek()

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