Skip to content

Commit 4f04cfc

Browse files
Switch from Calendar to OffsetDateTime in DateWrapper.
1 parent ee3af63 commit 4f04cfc

11 files changed

Lines changed: 131 additions & 167 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/localization/DateWrapper.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,61 @@
33
import edu.umd.cs.findbugs.annotations.NonNull;
44

55
import java.io.Serializable;
6+
import java.time.OffsetDateTime;
7+
import java.time.ZoneOffset;
68
import java.util.Calendar;
9+
import java.util.GregorianCalendar;
710

811
/**
9-
* A wrapper class that provides a field to describe if the date is precise or just an approximation.
12+
* A wrapper class that provides a field to describe if the date/time is precise or just an approximation.
1013
*/
1114
public class DateWrapper implements Serializable {
12-
@NonNull private final Calendar date;
15+
@NonNull private final OffsetDateTime offsetDateTime;
1316
private final boolean isApproximation;
1417

15-
public DateWrapper(@NonNull Calendar date) {
16-
this(date, false);
18+
/**
19+
* @deprecated Use {@link #DateWrapper(OffsetDateTime)} instead.
20+
*/
21+
@Deprecated
22+
public DateWrapper(@NonNull Calendar calendar) {
23+
this(calendar, false);
24+
}
25+
26+
/**
27+
* @deprecated Use {@link #DateWrapper(OffsetDateTime, boolean)} instead.
28+
*/
29+
@Deprecated
30+
public DateWrapper(@NonNull Calendar calendar, boolean isApproximation) {
31+
offsetDateTime = OffsetDateTime.ofInstant(calendar.toInstant(), ZoneOffset.UTC);
32+
this.isApproximation = isApproximation;
1733
}
1834

19-
public DateWrapper(@NonNull Calendar date, boolean isApproximation) {
20-
this.date = date;
35+
public DateWrapper(@NonNull OffsetDateTime offsetDateTime) {
36+
this(offsetDateTime, false);
37+
}
38+
39+
public DateWrapper(@NonNull OffsetDateTime offsetDateTime, boolean isApproximation) {
40+
this.offsetDateTime = offsetDateTime.withOffsetSameInstant(ZoneOffset.UTC);
2141
this.isApproximation = isApproximation;
2242
}
2343

2444
/**
25-
* @return the wrapped date.
45+
* @return the wrapped date/time as a {@link Calendar}.
46+
*
47+
* @deprecated use {@link #offsetDateTime()} instead.
2648
*/
49+
@Deprecated
2750
@NonNull
2851
public Calendar date() {
29-
return date;
52+
return GregorianCalendar.from(offsetDateTime.toZonedDateTime());
53+
}
54+
55+
/**
56+
* @return the wrapped date/time.
57+
*/
58+
@NonNull
59+
public OffsetDateTime offsetDateTime() {
60+
return offsetDateTime;
3061
}
3162

3263
/**

extractor/src/main/java/org/schabi/newpipe/extractor/localization/TimeAgoParser.java

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import org.schabi.newpipe.extractor.timeago.PatternsHolder;
55
import org.schabi.newpipe.extractor.utils.Parser;
66

7+
import java.time.OffsetDateTime;
8+
import java.time.ZoneOffset;
79
import java.time.temporal.ChronoUnit;
8-
import java.util.Calendar;
910
import java.util.Collection;
1011
import java.util.Map;
1112
import java.util.regex.Pattern;
@@ -16,7 +17,7 @@
1617
*/
1718
public class TimeAgoParser {
1819
private final PatternsHolder patternsHolder;
19-
private final Calendar consistentNow;
20+
private final OffsetDateTime now;
2021

2122
/**
2223
* Creates a helper to parse upload dates in the format '2 days ago'.
@@ -28,7 +29,7 @@ public class TimeAgoParser {
2829
*/
2930
public TimeAgoParser(PatternsHolder patternsHolder) {
3031
this.patternsHolder = patternsHolder;
31-
consistentNow = Calendar.getInstance();
32+
now = OffsetDateTime.now(ZoneOffset.UTC);
3233
}
3334

3435
/**
@@ -113,64 +114,34 @@ private boolean textualDateMatches(String textualDate, String agoPhrase) {
113114
}
114115

115116
private DateWrapper getResultFor(int timeAgoAmount, ChronoUnit chronoUnit) {
116-
final Calendar calendarTime = getNow();
117+
OffsetDateTime offsetDateTime = now;
117118
boolean isApproximation = false;
118119

119120
switch (chronoUnit) {
120121
case SECONDS:
121-
calendarTime.add(Calendar.SECOND, -timeAgoAmount);
122-
break;
123-
124122
case MINUTES:
125-
calendarTime.add(Calendar.MINUTE, -timeAgoAmount);
126-
break;
127-
128123
case HOURS:
129-
calendarTime.add(Calendar.HOUR_OF_DAY, -timeAgoAmount);
124+
offsetDateTime = offsetDateTime.minus(timeAgoAmount, chronoUnit);
130125
break;
131126

132127
case DAYS:
133-
calendarTime.add(Calendar.DAY_OF_MONTH, -timeAgoAmount);
134-
isApproximation = true;
135-
break;
136-
137128
case WEEKS:
138-
calendarTime.add(Calendar.WEEK_OF_YEAR, -timeAgoAmount);
139-
isApproximation = true;
140-
break;
141-
142129
case MONTHS:
143-
calendarTime.add(Calendar.MONTH, -timeAgoAmount);
130+
offsetDateTime = offsetDateTime.minus(timeAgoAmount, chronoUnit);
144131
isApproximation = true;
145132
break;
146133

147134
case YEARS:
148-
calendarTime.add(Calendar.YEAR, -timeAgoAmount);
149-
// Prevent `PrettyTime` from showing '12 months ago'.
150-
calendarTime.add(Calendar.DAY_OF_MONTH, -1);
135+
// minusDays is needed to prevent `PrettyTime` from showing '12 months ago'.
136+
offsetDateTime = offsetDateTime.minusYears(timeAgoAmount).minusDays(1);
151137
isApproximation = true;
152138
break;
153139
}
154140

155141
if (isApproximation) {
156-
markApproximatedTime(calendarTime);
142+
offsetDateTime = offsetDateTime.truncatedTo(ChronoUnit.HOURS);
157143
}
158144

159-
return new DateWrapper(calendarTime, isApproximation);
160-
}
161-
162-
private Calendar getNow() {
163-
return (Calendar) consistentNow.clone();
164-
}
165-
166-
/**
167-
* Marks the time as approximated by setting minutes, seconds and milliseconds to 0.
168-
*
169-
* @param calendarTime Time to be marked as approximated
170-
*/
171-
private void markApproximatedTime(Calendar calendarTime) {
172-
calendarTime.set(Calendar.MINUTE, 0);
173-
calendarTime.set(Calendar.SECOND, 0);
174-
calendarTime.set(Calendar.MILLISECOND, 0);
145+
return new DateWrapper(offsetDateTime, isApproximation);
175146
}
176147
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,17 @@
22

33
import org.schabi.newpipe.extractor.exceptions.ParsingException;
44

5-
import java.text.ParseException;
6-
import java.text.SimpleDateFormat;
7-
import java.util.Calendar;
8-
import java.util.Date;
9-
import java.util.TimeZone;
5+
import java.time.OffsetDateTime;
6+
import java.time.format.DateTimeParseException;
107

118
public final class MediaCCCParsingHelper {
129
private MediaCCCParsingHelper() { }
1310

14-
public static Calendar parseDateFrom(final String textualUploadDate) throws ParsingException {
15-
final Date date;
11+
public static OffsetDateTime parseDateFrom(final String textualUploadDate) throws ParsingException {
1612
try {
17-
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
18-
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
19-
date = sdf.parse(textualUploadDate);
20-
} catch (ParseException e) {
13+
return OffsetDateTime.parse(textualUploadDate);
14+
} catch (DateTimeParseException e) {
2115
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e);
2216
}
23-
24-
final Calendar uploadDate = Calendar.getInstance();
25-
uploadDate.setTime(date);
26-
return uploadDate;
2717
}
28-
2918
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/PeertubeParsingHelper.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.grack.nanojson.JsonArray;
44
import com.grack.nanojson.JsonObject;
5-
65
import org.schabi.newpipe.extractor.InfoItemsCollector;
76
import org.schabi.newpipe.extractor.Page;
87
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
@@ -12,11 +11,10 @@
1211
import org.schabi.newpipe.extractor.utils.Parser;
1312
import org.schabi.newpipe.extractor.utils.Utils;
1413

15-
import java.text.ParseException;
16-
import java.text.SimpleDateFormat;
17-
import java.util.Calendar;
18-
import java.util.Date;
19-
import java.util.TimeZone;
14+
import java.time.Instant;
15+
import java.time.OffsetDateTime;
16+
import java.time.ZoneOffset;
17+
import java.time.format.DateTimeParseException;
2018

2119
public class PeertubeParsingHelper {
2220
public static final String START_KEY = "start";
@@ -34,19 +32,12 @@ public static void validate(final JsonObject json) throws ContentNotAvailableExc
3432
}
3533
}
3634

37-
public static Calendar parseDateFrom(final String textualUploadDate) throws ParsingException {
38-
final Date date;
35+
public static OffsetDateTime parseDateFrom(final String textualUploadDate) throws ParsingException {
3936
try {
40-
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
41-
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
42-
date = sdf.parse(textualUploadDate);
43-
} catch (ParseException e) {
37+
return OffsetDateTime.ofInstant(Instant.parse(textualUploadDate), ZoneOffset.UTC);
38+
} catch (DateTimeParseException e) {
4439
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e);
4540
}
46-
47-
final Calendar uploadDate = Calendar.getInstance();
48-
uploadDate.setTime(date);
49-
return uploadDate;
5041
}
5142

5243
public static Page getNextPage(final String prevPageUrl, final long total) {

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@
2121
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
2222
import org.schabi.newpipe.extractor.utils.Parser;
2323
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
24-
import org.schabi.newpipe.extractor.utils.Utils;
2524

2625
import javax.annotation.Nonnull;
2726
import java.io.IOException;
2827
import java.net.MalformedURLException;
2928
import java.net.URL;
3029
import java.net.URLEncoder;
31-
import java.text.ParseException;
32-
import java.text.SimpleDateFormat;
33-
import java.util.*;
30+
import java.time.OffsetDateTime;
31+
import java.time.format.DateTimeFormatter;
32+
import java.time.format.DateTimeParseException;
33+
import java.util.Collections;
34+
import java.util.HashMap;
35+
import java.util.List;
3436

3537
import static java.util.Collections.singletonList;
3638
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
@@ -95,23 +97,16 @@ static boolean checkIfHardcodedClientIdIsValid() {
9597
}
9698
}
9799

98-
public static Calendar parseDateFrom(String textualUploadDate) throws ParsingException {
99-
Date date;
100+
public static OffsetDateTime parseDateFrom(String textualUploadDate) throws ParsingException {
100101
try {
101-
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
102-
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
103-
date = sdf.parse(textualUploadDate);
104-
} catch (ParseException e1) {
102+
return OffsetDateTime.parse(textualUploadDate);
103+
} catch (DateTimeParseException e1) {
105104
try {
106-
date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse(textualUploadDate);
107-
} catch (ParseException e2) {
105+
return OffsetDateTime.parse(textualUploadDate, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss +0000"));
106+
} catch (DateTimeParseException e2) {
108107
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"" + ", " + e1.getMessage(), e2);
109108
}
110109
}
111-
112-
final Calendar uploadDate = Calendar.getInstance();
113-
uploadDate.setTime(date);
114-
return uploadDate;
115110
}
116111

117112
/**

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.grack.nanojson.JsonParser;
66
import com.grack.nanojson.JsonParserException;
77
import com.grack.nanojson.JsonWriter;
8-
98
import org.jsoup.Jsoup;
109
import org.jsoup.nodes.Document;
1110
import org.schabi.newpipe.extractor.downloader.Response;
@@ -22,13 +21,18 @@
2221
import java.net.MalformedURLException;
2322
import java.net.URL;
2423
import java.net.URLDecoder;
25-
import java.text.ParseException;
26-
import java.text.SimpleDateFormat;
27-
import java.util.*;
24+
import java.time.OffsetDateTime;
25+
import java.time.format.DateTimeParseException;
26+
import java.util.Collections;
27+
import java.util.HashMap;
28+
import java.util.List;
29+
import java.util.Map;
2830

2931
import static org.schabi.newpipe.extractor.NewPipe.getDownloader;
3032
import static org.schabi.newpipe.extractor.utils.JsonUtils.EMPTY_STRING;
31-
import static org.schabi.newpipe.extractor.utils.Utils.*;
33+
import static org.schabi.newpipe.extractor.utils.Utils.HTTP;
34+
import static org.schabi.newpipe.extractor.utils.Utils.HTTPS;
35+
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
3236

3337
/*
3438
* Created by Christian Schabesberger on 02.03.16.
@@ -176,19 +180,12 @@ public static String getFeedUrlFrom(final String channelIdOrUser) {
176180
}
177181
}
178182

179-
public static Calendar parseDateFrom(String textualUploadDate) throws ParsingException {
180-
final Date date;
183+
public static OffsetDateTime parseDateFrom(String textualUploadDate) throws ParsingException {
181184
try {
182-
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
183-
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
184-
date = sdf.parse(textualUploadDate);
185-
} catch (ParseException e) {
185+
return OffsetDateTime.parse(textualUploadDate);
186+
} catch (DateTimeParseException e) {
186187
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e);
187188
}
188-
189-
final Calendar uploadDate = Calendar.getInstance();
190-
uploadDate.setTime(date);
191-
return uploadDate;
192189
}
193190

194191
public static JsonObject getInitialData(String html) throws ParsingException {

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeFeedInfoItemExtractor.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
import org.schabi.newpipe.extractor.stream.StreamType;
88

99
import javax.annotation.Nullable;
10-
import java.text.ParseException;
11-
import java.text.SimpleDateFormat;
12-
import java.util.Calendar;
13-
import java.util.Date;
14-
import java.util.TimeZone;
10+
import java.time.OffsetDateTime;
11+
import java.time.format.DateTimeFormatter;
12+
import java.time.format.DateTimeParseException;
1513

1614
public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
1715
private final Element entryElement;
@@ -62,19 +60,11 @@ public String getTextualUploadDate() {
6260
@Nullable
6361
@Override
6462
public DateWrapper getUploadDate() throws ParsingException {
65-
final Date date;
6663
try {
67-
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+00:00");
68-
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
69-
date = dateFormat.parse(getTextualUploadDate());
70-
} catch (ParseException e) {
64+
return new DateWrapper(OffsetDateTime.parse(getTextualUploadDate(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
65+
} catch (DateTimeParseException e) {
7166
throw new ParsingException("Could not parse date (\"" + getTextualUploadDate() + "\")", e);
7267
}
73-
74-
final Calendar calendar = Calendar.getInstance();
75-
calendar.setTime(date);
76-
77-
return new DateWrapper(calendar);
7868
}
7969

8070
@Override

0 commit comments

Comments
 (0)