java - settimana - simpledateformat




Come ottenere il primo giorno della settimana e del mese attuali? (8)

java.time

Il framework java.time in Java 8 e java.time successive sostituisce le vecchie classi java.util.Date/.Calendar. Le vecchie classi hanno dimostrato di essere fastidiose, confuse e imperfette. Evitalo.

Il framework java.time si ispira alla libreria Joda-Time grande successo, definita da JSR 310 , estesa dal progetto ThreeTen-Extra e spiegata nel Tutorial .

Instant

La classe Instant rappresenta un momento sulla timeline in UTC .

Il framework java.time ha una risoluzione di nanosecondi o 9 cifre di un secondo frazionario. I millisecondi sono solo 3 cifre di un secondo frazionario. Poiché la risoluzione in millisecondi è comune, java.time include un pratico metodo di produzione.

long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );

millisecondsSinceEpoch: 1446959825213 è istantaneo: 2015-11-08T05: 17: 05.213Z

ZonedDateTime

Per considerare la settimana corrente e il mese corrente, è necessario applicare un particolare fuso orario.

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

In zoneId: America / Montreal ovvero: 2015-11-08T00: 17: 05.213-05: 00 [America / Montreal]

Mezzo aperto

Nel lavoro con data e ora, usiamo comunemente l'approccio Half-Open per definire un intervallo di tempo. L'inizio è inclusivo mentre il finale in esclusiva . Piuttosto che cercare di determinare l'ultimo frazione di secondo della fine della settimana (o del mese), otteniamo il primo momento della settimana successiva (o del mese). Quindi una settimana va dal primo momento del lunedì e sale fino a non includere il primo momento del lunedì successivo .

Facciamo il primo giorno della settimana e l'ultimo. Il framework java.time include uno strumento per questo, il metodo with e l'enum ChronoField .

Per impostazione predefinita, java.time utilizza lo standard ISO 8601 . Quindi il lunedì è il primo giorno della settimana (1) e domenica è l'ultimo (7).

ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );

Quella settimana va da: 2015-11-02T00: 17: 05.213-05: 00 [America / Montreal] al 2015-11-09T00: 17: 05.213-05: 00 [America / Montreal]

Oops! Guarda l'ora del giorno su quei valori. Vogliamo il primo momento della giornata. Il primo momento della giornata non è sempre 00:00:00.000 causa dell'ora legale (DST) o di altre anomalie. Quindi dovremmo lasciare che java.time esegua l'aggiustamento per nostro conto. Per fare ciò, dobbiamo passare attraverso la classe LocalDate .

ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );

Quella settimana va da: 2015-11-02T00: 00-05: 00 [America / Montreal] al 2015-11-09T00: 00-05: 00 [America / Montreal]

E lo stesso per il mese.

ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );

Questo mese va da: 2015-11-01T00: 00-04: 00 [America / Montreal] al 2015-12-01T00: 00-05: 00 [America / Montreal]

YearMonth

Un altro modo per vedere se un paio di momenti sono nello stesso mese è quello di verificare lo stesso valore YearMonth .

Ad esempio, supponendo che thisZdt e thatZdt siano entrambi oggetti ZonedDateTime :

boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;

millisecondi

Consiglio vivamente di non eseguire il vostro lavoro data-ora in millisecondi-da-epoca. Questo è infatti il ​​modo in cui le lezioni di data-ora tendono a funzionare internamente, ma abbiamo le classi per una ragione. Gestire un conteggio da un'epoca è maldestro in quanto i valori non sono comprensibili dagli esseri umani, pertanto il debug e la registrazione sono difficili e soggetti a errori. E, come abbiamo già visto, potrebbero essere in gioco diverse risoluzioni; le vecchie classi Java e la libreria Joda-Time utilizzano millisecondi, mentre i database come Postgres utilizzano i microsecondi e ora java.time utilizza nanosecondi.

Gestiresti il ​​testo come bit o lascerai che classi come String , StringBuffer e StringBuilder gestiscano tali dettagli?

Ma se insisti, da un ZonedDateTime ottieni un Instant , e da questo ottieni un millisecondo-count-from-epoch. Ma tieni presente che questa chiamata può significare perdita di dati . Qualsiasi microsecondo o nanosecondo che potresti avere nel tuo ZonedDateTime / Instant verrà troncato (perso).

long millis = firstOfWeek.toInstant().toEpochMilli();  // Possible data loss.

Ho la data di diversi eventi espressi in millisecondi [1], e voglio sapere quali eventi sono all'interno della settimana corrente e del mese corrente, ma non riesco a capire come ottenere il primo giorno (giorno / mese / anno ) della settimana corrente e convertirlo in millisecondi, lo stesso per il primo giorno del mese.

[1]Since January 1, 1970, 00:00:00 GMT

Attenzione!

while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
    calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}

è una buona idea, ma c'è qualche problema: ad esempio, vengo dall'Ucraina e calendar.getFirstDayOfWeek () nel mio paese è 2 (lunedì). E oggi è 1 (domenica). In questo caso calendar.add non chiamato.

Quindi, il modo corretto è cambiare ">" in "! =":

while (calendar.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek()) {...

Ho creato alcuni metodi per questo:

public static String catchLastDayOfCurrentWeek(String pattern) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.clear(Calendar.MINUTE);
    cal.clear(Calendar.SECOND);
    cal.clear(Calendar.MILLISECOND);

    cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());

    return calendarToString(cal, pattern);
}

public static String catchLastDayOfCurrentWeek(String pattern) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.clear(Calendar.MINUTE);
    cal.clear(Calendar.SECOND);
    cal.clear(Calendar.MILLISECOND);

    cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());

    cal.add(Calendar.WEEK_OF_YEAR, 1);
    cal.add(Calendar.MILLISECOND, -1);

    return calendarToString(cal, pattern);
}

public static String catchTheFirstDayOfThemonth(Integer month, pattern padrao) {
    Calendar cal = GregorianCalendar.getInstance();
    cal.setTime(new Date());
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DAY_OF_MONTH, 1);

    return calendarToString(cal, pattern);
}

public static String catchTheLastDayOfThemonth(Integer month, String pattern) {
    Calendar cal = GregorianCalendar.getInstance();
    cal.setTime(new Date());
    cal.set(cal.get(Calendar.YEAR), month, cal.getActualMaximum(Calendar.DAY_OF_MONTH));

    return calendarToString(cal, pattern);
}

public static String calendarToString(Calendar calendar, String pattern) {
    if (calendar == null) {
        return "";
    }
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    return format.format(calendar.getTime());
}

Puoi vedere di più here .


Il primo giorno della settimana può essere determinato con l'aiuto di java.util.Calendar come segue:

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
    calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
long firstDayOfWeekTimestamp = calendar.getTimeInMillis();

Il primo giorno del mese può essere determinato come segue:

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DATE) > 1) {
    calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of month.
}
long firstDayOfMonthTimestamp = calendar.getTimeInMillis();

Piuttosto prolisso, sì.

Java 7 verrà fornito con un'API Date and Time molto migliorata ( JSR-310 ). Se non puoi ancora cambiare, puoi usare JodaTime che rende tutto meno complicato:

DateTime dateTime = new DateTime(timestamp);
long firstDayOfWeekTimestamp = dateTime.withDayOfWeek(1).getMillis();

e

DateTime dateTime = new DateTime(timestamp);
long firstDayOfMonthTimestamp = dateTime.withDayOfMonth(1).getMillis();

Per ottenere il primo giorno del mese, è sufficiente ottenere una Date e impostare il giorno corrente al giorno 1 del mese. Cancella ora, minuto, secondo e millisecondo se ne hai bisogno.

private static Date firstDayOfMonth(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   calendar.set(Calendar.DATE, 1);
   return calendar.getTime();
}

Il primo giorno della settimana è la stessa cosa, ma utilizzando Calendar.DAY_OF_WEEK invece

private static Date firstDayOfWeek(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   calendar.set(Calendar.DAY_OF_WEEK, 1);
   return calendar.getTime();
}

Questa settimana in millisecondi:

// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);

// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
System.out.println("Start of this week:       " + cal.getTime());
System.out.println("... in milliseconds:      " + cal.getTimeInMillis());

// start of the next week
cal.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println("Start of the next week:   " + cal.getTime());
System.out.println("... in milliseconds:      " + cal.getTimeInMillis());

Questo mese in millisecondi:

// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);

// get start of the month
cal.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Start of the month:       " + cal.getTime());
System.out.println("... in milliseconds:      " + cal.getTimeInMillis());

// get start of the next month
cal.add(Calendar.MONTH, 1);
System.out.println("Start of the next month:  " + cal.getTime());
System.out.println("... in milliseconds:      " + cal.getTimeInMillis());

Simple Solution:
package com.util.calendarutil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class CalUtil {
    public static void main(String args[]){
        DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
        Date dt = null;
        try {
            dt = df.parse("23/01/2016");
        } catch (ParseException e) {
            System.out.println("Error");
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
        Date startDate = cal.getTime();
        cal.add(Calendar.DATE, 6);
        Date endDate = cal.getTime();
        System.out.println("Start Date:"+startDate+"End Date:"+endDate);


    }

}

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;

/**
This Program will display day for, 1st and last days in a given month and year

@author Manoj Kumar Dunna
Mail Id : [email protected]
*/
public class DayOfWeek {
    public static void main(String[] args) {
        String strDate = null;
        int  year = 0, month = 0;
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter YYYY/MM: ");
        strDate = sc.next();
        Calendar cal = new GregorianCalendar();
        String [] date = strDate.split("/");
        year = Integer.parseInt(date[0]);
        month = Integer.parseInt(date[1]);
        cal.set(year, month-1, 1);
        System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DAY_OF_YEAR, -1);
        System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
    }
}




date