简体   繁体   中英

How to parse from week/year to dd/mm/yyyy

I'm trying to parse a String that contains week/year information to a normal dd-mm-yyyy format

import java.util.Calendar;
import java.util.*;
import java.text.*;
import java.util.GregorianCalendar;

public class FromWeektoDate {

public static void main(String[] args) {
    Calendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setFirstDayOfWeek(Calendar.SUNDAY);
    gregorianCalendar.setMinimalDaysInFirstWeek(4);

     String SemaineYear[] = "20/2018".split("/");


         int s = Integer.parseInt(SemaineYear[0]);
         int a = Integer.parseInt(SemaineYear[1]);
      int numWeekofYear = s;  //INPUT
       int year = a;         //INPUT

    gregorianCalendar.set(Calendar.YEAR , year);
    gregorianCalendar.set(Calendar.WEEK_OF_YEAR , numWeekofYear);

  Date date = new Date();

     date.setDay(gregorianCalendar.get(Calendar.DAY_OF_MONTH) );   
     date.setMonth(gregorianCalendar.get(Calendar.MONTH)  + 1 );
     date.setYear(gregorianCalendar.get
                        (Calendar.YEAR));

    System.out.println(date);
}
}

but I'm getting this error :

 /tmp/java_5kSPR0/FirstDayofWeek.java:26: error: cannot find symbol date.setDay(gregorianCalendar.get(Calendar.DAY_OF_MONTH) ); ^ symbol: method setDay(int) location: variable date of type Date /tmp/java_5kSPR0/FirstDayofWeek.java:27: warning: [deprecation] setMonth(int) in Date has been deprecated 

If you don't care what day within the week you want, you can simply start from New Year's Day and add as many weeks as you like:

LocalDate date = LocalDate.of(year, 1, 1).plusWeeks(weekOfYear - 1)

For your example (20th week of 2018), this gives me 2018-05-14 .

java.time

java.time, the modern Java date and time API, can do that.

    // In Malta weeks begin on Sunday, and there must be at least 4 days
    // of a week in a year for it to be week 1 of that year
    WeekFields wf = WeekFields.of(Locale.forLanguageTag("mt"));

    DateTimeFormatter yearWeekFormatter = new DateTimeFormatterBuilder()
            .appendValue(wf.weekOfWeekBasedYear(), 2)
            .appendLiteral('/')
            .appendValue(wf.weekBasedYear(), 4)
            .parseDefaulting(ChronoField.DAY_OF_WEEK, wf.getFirstDayOfWeek().getValue())
            .toFormatter();

    String weekString = "20/2018";
    LocalDate sundayOfWeek20 = LocalDate.parse(weekString, yearWeekFormatter);
    System.out.println(sundayOfWeek20);

Output from this snippet is:

2018-05-13

To format into 13/05/2018 use another DateTimeFormatter :

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    System.out.println(sundayOfWeek20.format(dateFormatter));

13/05/2018

I interpreted from your code that your require a week scheme where the week starts on Sunday and there are at least 4 days in the first week. The WeekFields class is used for defining such a scheme. If your requirement comes out of a specific locale (Malta or Ireland), I recommend using that locale for defining the WeekFields object to use, as I do in the snippet above. If, on the other hand, your requirement doesn't come from some locale, it's better to specify it more directly:

    WeekFields wf = WeekFields.of(DayOfWeek.SUNDAY, 4);

I am using java.time's built-in parsing mechanism through LocalDate.parse . No need to hand parse or otherwise reinvent the wheel. To have the formatter understand our week scheme I pass TemporalField objects that I get from the WeekFields to DateTimeFormatterBuilder.appenValue . To parse into a LocalDate we need to add a day of week (even though you said you don't care which). I use the call to parseDefaulting for that.

Frankly I was surprised to see how flexible java.time was to meet your requirements. Even though I knew already that it is a pleasure to work with it.

The date-time classes that you used — Calendar , GregorianCalendar and Date — are poorly designed and long outdated. I recommend you don't use them.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Just use getTime to get Date object

Date date =  gregorianCalendar.getTime();

Returns a Date object representing this Calendar's time value (millisecond offset from the Epoch").

Or use SimpleDateFormat for parsing specific format

SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
dateFormat.setTimeZone(gregorianCalendar.getTimeZone());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM