Incerteza
Incerteza

Reputation: 34934

Parse a month name and create a date range

Given the current year and a an arbitrary month in a full string format ("april"), how do I create a date range for this month? For example, if I'm given "june" I want to create date1 = "2014-06-01" and date2 = "2014-06-31". I tried to parse a month:

DateTime.parse("january")
DateTime.parse("2014-january")
DateTime.parse("2014-january-01")

but it caused the error saying its argument was wrong. I could use another overloaded version of parse but it turned out to be pretty difficult due to its DateTimeFormatter parameters which I had no idea how to use.

I could create a map containing all months and the amount of days they, but since Joda-Time has a standard way to do that I decided not to do that.

How do I do this?

Upvotes: 2

Views: 2199

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 339601

Obviously it would be better if you could be passed a month number rather than a localized month name. But if you have no way to change that, here we go with some example code in Java using Joda-Time 2.3.

You'll have to adjust syntax to Scala on your own.

My code here was inspired by the answer by PopoFibo.

DateTimeZone timeZone = DateTimeZone.forID( "Asia/Macau" );
DateTime now = new DateTime( timeZone );

// Gather inputs
int currentYear = now.getYear();
String givenMonth = "april";
String doubleDigitOne = new java.text.DecimalFormat( "00" ).format( 1 );

// Assemble inputs
String input = currentYear + "-" + givenMonth + "-" + doubleDigitOne;

// Parse inputs.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MMM-dd" ).withLocale( java.util.Locale.ENGLISH ).withZone( timeZone );
DateTime monthStart = formatter.parseDateTime( input );

Dump to console…

System.out.println( "now: " + now );
System.out.println( "input: " + input );
System.out.println( "monthStart: " + monthStart );
System.out.println( "monthStart in UTC/GMT: " + monthStart.withZone( DateTimeZone.UTC ) );

When run…

now: 2014-02-13T21:12:01.901+08:00
input: 2014-april-01
monthStart: 2014-04-01T00:00:00.000+08:00
monthStart in UTC/GMT: 2014-03-31T16:00:00.000Z

That solves your funky problem of being passed a month name.

As for defining a span of time representing the entire month… You can search StackOverflow for many already-answered questions on that topic including several long explanatory ones by me. Search for terms like: joda, start of month, start of week, half-open, inclusive, exclusive. Hint: Interval is your new friend.

Upvotes: 1

Ashalynd
Ashalynd

Reputation: 12573

import org.joda.time.format.DateTimeFormat
import org.joda.time.LocalDate

def monthDateRange(month:String) = {
    val ld = LocalDate.parse(month, DateTimeFormat.forPattern("MMMM"))
    val end = ld.plusMonths(1).withDayOfMonth(1).minusDays(1).getDayOfMonth
    (1,end)
}

Upvotes: 0

StoopidDonut
StoopidDonut

Reputation: 8617

I'm not that well versed with scala but since it's JVM, I will give it a shot, correct me if I make any syntax errors:

var strDate = "January"
var format = DateTimeFormat.forPattern("MMM")
var date = format.parseDateTime(strDate)
println(date)

var monthStart = new DateTime().withYear(2014).withMonthOfYear(date.getMonthOfYear()).withDayOfMonth(date.dayOfMonth().getMinimumValue())
var monthEnd = new DateTime().withYear(2014).withMonthOfYear(date.getMonthOfYear()).withDayOfMonth(date.dayOfMonth().getMaximumValue())

println("Month Start : " + monthStart)
println("Month End : " + monthEnd)

Without the year, jodatime would default to 2000 hence while setting the monthStart and monthEnd I set it to 2014 explicitly.

In Java, I get the output like:

Month Start : 2014-01-01T15:00:26.174+05:30
Month End : 2014-01-31T15:00:26.179+05:30

Let me know how it goes!

Upvotes: 4

serejja
serejja

Reputation: 23881

import org.joda.time.format.DateTimeFormat
import org.joda.time.DateTime
import java.util.Locale

val dt = "2014-january-01"
val df = DateTimeFormat.forPattern("yyyy-MMMMM-dd").withLocale(Locale.US)
DateTime.parse(dt, df)

This gives you:

res16: org.joda.time.DateTime = 2014-01-01T00:00:00.000+02:00

Then, you may do something like this:

val start = res16.dayOfMonth.withMinimumValue
val end = res16.dayOfMonth.withMaximumValue

Upvotes: 2

Related Questions