I want to do some formatting in my webapp, using MessageFormat, DateFormat, DecimalFormat, etc.
Since these are not thread-safe, one static instance for each usage won't work, but it seems wasteful to create a new XXXXFormat object each time one is needed. Caching and re-using them with a ThreadLocal seems like an obvious optimization.
This seems like a very common pattern, so I'm wondering if there are any appropriate libraries.
Instead of calling:
DecimalFormat formatter = new DecimalFormat("###,##0.00");
String formatted = formatter.format(value);
every time I need to format something, why not:
String formatted = FormatCache.formatDecimal("###,##0.00",numberValue);
where FormatCache would do the ThreadLocal caching with a HashMap keyed on the format pattern?
Presumably there'd be other methods like:
String FormatCache.formatDecimal(String, Number);
String FormatCache.formatDate(String, Date);
String FormatCache.formatMessage(String, Object...);
tl;dr
Cache a thread-safe DateTimeFormatter object (immutable).
Never use SimpleDateFormat. Use only java.time package for date-time work.
java.time
The troublesome old date-time classes such as DateFormat & SimpleDateFormat are now supplanted by the modern java.time classes. Specifically here, the DateTimeFormatter class.
Immutable objects, thread-safe
The java.time classes were designed to be Immutable Objects. This means that rather than modifying any content in the object, a new distinct object is generated. The original is left intact.
This, and other techniques, make the java.time classes thread-safe by design and are so documented.
DateTimeFormatter
DateTimeFormatter dateTimeFormatterFullQuébec = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
You can cache that object dateTimeFormatterFullQuébec, keep it around.
ZoneId
Likewise, you could keep a ZoneId time zone object cached.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId zoneMontréal = ZoneId.of( "America/Montreal" ) ;
Then use them any time, even across threads.
ZonedDateTime zdt = ZonedDateTime.now( zoneMontréal ) ;
String output = zdt.format( dateTimeFormatterFullQuébec ) ;
dimanche 4 mars 2018 à 18:36:32 Eastern Standard Time
The java.time objects such as ZonedDateTime and Instant are also immutable and thread-safe, just like the ZoneId & DateTimeFormatter. You can cache all of these, and use them across threads.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Apache Commons Lang has FastDateFormat, which solves the problem the right way (in my opinion), by just being threadsafe to begin with:
FastDateFormat is a fast and thread-safe version of SimpleDateFormat.
This class can be used as a direct replacement to SimpleDateFormat in most formatting situations. This class is especially useful in multi-threaded server environments. SimpleDateFormat is not thread-safe in any JDK version, nor will it be as Sun have closed the bug/RFE.
You should be really careful with something like that. The standard (simple) formaters are not threadsafe. I've ran into some multithread related issues with some shared/cached formaters, but that was some years ago (Java 1.4). If you check the JavaDocs (SimpleDateFormat), you will notice the following:
Synchronization
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Related
I need to format the Java Date object into a String like yyyyMMdd (round to day). For e.g, 20180129. I have the following implementation:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.format(roundedDate);
The code works most the time, but sometimes it'll generate results like 2018129, which is not what I want. So I'll have both 20180129 and 2018129 in my database.
The app consumes messages from a MQ and ummarshalls the timestamp in the message into a Java Date object. And it formats the date into a the above String.
The issue is that I cannot reproduce the issue in debug mode. It always produces the expected results in the debugger. But after I ran it on a server (in Docker) for some time, I see such corrupted data.
I wonder why the SimpleDateFormat could have such undetermined behavior given a valid Date object? Any idea will be appreciated.
SimpleDateFormat is not thread-safe, see this excellent article.
java.time.format.DateTimeFormatter is the modern thread-safe implementation of this functionality in the core Java.
tl;dr
Use the thread-safe java.time classes instead.
Specifically, use LocalDate and DateTimeFormatter.BASIC_ISO_DATE.
LocalDate.parse(
"2018129" ,
DateTimeFormatter.BASIC_ISO_DATE
)
2018-01-29
LocalDate.now()
.format( DateTimeFormatter.BASIC_ISO_DATE )
20180129
Thread-safety
You do not provide enough information to diagnose your problem. I would guess either:
You are using those legacy date-time objects across threads, and they were not designed to be thread-safe. Instead use the java.time classes which are designed to be thread-safe by design via immutable objects pattern.
Something is going wrong during whatever you are doing in this mysterious “date rounding” which you mention but neglect to explain.
Wrong data type
timestamp in the message into a Java Date object.
You are putting a date-only value into a date-with-time-of-day type. Square peg, round hole.
Instead, use a date-only type for a date-only value: LocalDate.
ISO 8601
Your desired format YYYYMMDD happens to be defined in the ISO 8601 standard, as the “basic” variant where the use of delimiters is minimized.
Java provides a DateTimeFormatter object for this purpose: DateTimeFormatter.BASIC_ISO_DATE. So no need to define a formatting pattern.
String input = "2018129" ;
LocalDate ld = LocalDate.parse( input , DateTimeFormatter.BASIC_ISO_DATE ) ;
To generate such a string, use the same formatter.
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
String output = today.format( DateTimeFormatter.BASIC_ISO_DATE ) ;
By the way, I recommend using the full-length versions of ISO 8601 formats rather than the compact “basic” variants. The few bytes saved are not worth giving up the readability and reduced ambiguity, in my experience. Plus, the java.time classes use the full-length ISO 8601 formats by default when parsing/generating String objects, so you can dispense with DateTimeFormatter objects entirely.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I'd like to know if Oracle is able to compare dates with different Timezones, as in:
12/26/2016 3:58:16.491476 AM -06:00 > 12/26/2016 3:58:16.491476 AM +05:00
Btw, I'm using JPA to do this comparison, the idea would be to look for all the rows created an hour ago.
I found that I might be able to use the After keyword to look for it (i.e. findMeasureDateAfter)
Very easy to check in Oracle. The answer is YES. Please note, in the illustration below the output shows timestamps using my session's NLS settings (I didn't care to change them).
with
inputs ( ts1, ts2 ) as (
select to_timestamp_tz('12/26/2016 3:58:16.491476 AM -06:00',
'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM'),
to_timestamp_tz('12/26/2016 3:58:16.491476 AM +05:00',
'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM') from dual
)
select ts1, ts2, case when ts1 > ts2 then 'ts1 > ts2'
when ts1 = ts2 then 'ts1 = ts2'
when ts1 < ts2 then 'ts1 < ts2'
end as comparison,
ts1 - ts2 as difference
from inputs
;
TS1 TS2 COMPARISON DIFFERENCE
----------------------------- ----------------------------- ---------- -------------------
26-DEC-16 03.58.16.491 AM -06 26-DEC-16 03.58.16.491 AM +05 ts1 > ts2 +00 11:00:00.000000
If you are pulling the data from an Oracle table based on a predicate like this, it is much better to do that work in the database - so how this would be done in Java is irrelevant. (You certainly don't want to fetch all the rows, only to ignore most of them after you check the timestamp in Java.) Of course, if you need "the last hour" you would compare against systimestamp - 1/24.
ISO 8601
First, if those inputs are actually strings as presented in the Question, use standard ISO 8601 formats instead if at all possible. The standard formats are intuitive to humans and easier to parse by computers. Indeed, the java.time classes use ISO 8601 formats by default when parsing/generating strings.
java.time
While I do not know about the the query in Oracle (I'm a Postgres man myself), I can show how to form the query more on the Java side.
Ideally we would parse that input string as a OffsetDateTime as it lacks an indication of time zone, only has offset-from-UTC. A zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST). A time zone is named in format of continent/region such as America/Montreal.
Unfortunately, the java.time implementation in Java 8 has some bugs around parsing offset-from-UTC in the DateTimeFormatter class. So until Java 9, here is a bit of hack code to parse as a ZonedDateTime and convert to the more appropriate OffsetDateTime.
String input = "12/26/2016 3:58:16.491476 AM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "MM/dd/uuuu h:m:s.SSSSSS a z" , Locale.ENGLISH );
OffsetDateTime odt = ZonedDateTime.parse ( input , f ).toOffsetDateTime ();
odt.toString(): 2016-12-26T03:58:16.491476-06:00
Repeat for your ending moment.
If your JDBC driver supports JDBC 4.2 or later, you may be able to pass these java.time types directly via PreparedStatement::setObject.
If not, convert to java.sql types. To convert, look to new methods added to the old classes. The from method takes an Instant which is a moment on the timeline in UTC. You can think of an Instant as a OffsetDateTime stripped of its offset. Call OffsetDateTime::toInstant to extract an Instant.
java.sql.Timestamp ts = java.sql.Timestamp.from( odt.toInstant() ) ;
Do this for both your beginning and ending moments. Pass these java.sql.Timestamp objects to your PreparedStatement.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Is it possible to format a date time in Java using the SimpleDateFormat class to give the timezone part of a date without having the +0000 after it.
Edit
We are changing the Default Timezone within Java as follows:
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
Unfortunately, I am in no position to remove this code. I would hazard a guess at the whole system stopping working. I think the initial author put this in to work around some day light saving issues.
With this in mind, I want to format the date as:
2011-12-27 09:00 GMT
or
2011-12-27 09:00 BST
I can only get the SimpleDateFormat to output as:
2011-12-27 09:00:00 GMT+00:00
which uses the format string yyyy-MM-dd HH:mm:ss z
I cannot see anywhere where the simple timezone has any reference to winter time (GMT) id or summer time id (BST).
This Question and the Answers are now outmoded. They use old date-time classes outmoded by the java.time framework built into Java 8 and later. The old classes are poorly designed, confusing, and troublesome; Avoid them.
Avoid 3-4 Letter Zone Codes
Avoid the 3-4 letter codes such as BST. They are neither standardized nor unique. They do not actually represent time zones. And they add even more confusion to the problem of Daylight Saving Time (DST).
Instead, use proper time zones. Most are continent/region format such as Europe/London.
Avoid setting default time zone
Calling java.util.TimeZone.setDefault should be done only in the most extreme cases. This call affects all code running in all threads of all apps within the JVM immediately during runtime.
Instead, in all your date-time code, specify the desired/expected time zone. If omitted, Java falls back by implicitly relying on the JVM’s current default time zone. As noted above this default can change at any moment during runtime! Instead, specify explicitly. If you specify your desired/expected time zone as a passed argument routinely then the current default time zone is moot, irrelevant.
java.time
The java.time framework is built into Java 8 and later. See Tutorial. Defined by JSR 310. Inspired by the highly successful Joda-Time library.
Instant
An Instant is a moment on the timeline in UTC.
The following example shows how the java.time classes can parse/generate strings by default if in standard ISO 8601 format, with no need to specify a parsing pattern. Use DateTimeFormatter class to specify other non-standard patterns.
Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
ZonedDateTime
Apply a time zone as needed, producing a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Generating Strings
You can produce textual representations of the ZonedDateTime object using a DateTimeFormatter. You can specify custom patterns. Or, as I recommend, let java.time localize for you.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
Best to specify the desired/expected Locale for the same reason as time zone… the JVM’s current default can be changed at any moment by any code in any thread of any app running within the JVM. The Locale determines (a) the human language used for names of day & month, and (b) the cultural norms such as commas versus periods and the order of the parts such as month or day or year coming first.
formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I think that you are using the correct pattern for your requirements, however the JDK doesn't know the name of your timezone, so it switches over to using a GMT offset value instead.
When I format a date using your pattern, I get "GMT" for the timezone part.
What does TimeZone.getDefault().getDisplayName() give you? For me, I get "Greenwich Mean Time".
Not an elegant solution at all but it works for us. I had to create a custom implementation for DateFormat/SimpleDateFormat. This looks like something as follows:
static {
// this would be initialized like something as follows when the application starts
// which causes the headaches of SimpleDateFormat not to work...
SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");
TimeZone.setDefault(tz);
}
// therefore this class will workaround the issue,
public class OurOwnCustomDateFormat
extends SimpleDateFormat {
/** The pattern to use as the format string. */
protected String pattern;
public OurOwnCustomDateFormat(String pattern) {
super(pattern);
// store the pattern
this.pattern = pattern;
}
#Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
// custom implementation to format the date and time based on our TimeZone
toAppendTo.insert(pos.getBeginIndex(), "the date with our custom format calculated here");
return toAppendTo;
}
Since I cannot reproduce this problem on my computer. I guess this would relate about localization. Try this
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",Locale.US).format(new Date()));
Hope this helps.
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())); for me just returns 2011-11-22 13:42:16 GMT - so appears to work as you wish. Looks like it might be a problem elsewhere, you shouldn't need to create your own formatter class though.
I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have a Java class that takes in the latitude/longitude of a location and returns the GMT offset when daylight savings time is on and off. I am looking for an easy way to determine in Java if the current date is in daylight savings time so I can apply the correct offset. Currently I am only performing this calculation for U.S. timezones although eventually I would like to expand this to global timezones as well.
This is the answer for the machine on which the question is being asked:
TimeZone.getDefault().inDaylightTime( new Date() );
A server trying to figure this out for a client will need the client's time zone. See #Powerlord answer for the reason why.
For any particular TimeZone
TimeZone.getTimeZone( "US/Alaska").inDaylightTime( new Date() );
tl;dr
ZoneId.of( "America/Montreal" ) // Represent a specific time zone, the history of past, present, and future changes to the offset-from-UTC used by the people of a certain region.
.getRules() // Obtain the list of those changes in offset.
.isDaylightSavings( // See if the people of this region are observing Daylight Saving Time at a specific moment.
Instant.now() // Specify the moment. Here we capture the current moment at runtime.
) // Returns a boolean.
java.time
Here is the modern java.time (see Tutorial) version of the correct Answer by mamboking.
A ZoneId represents a time zone. The class knows the rules that tell if DST applies to a particular time zone.
The ZoneRules class models all the historic and future transitions for a time-zone.
An Instant is a moment on the timeline in UTC.
A ZonedDateTime is the result of applying a ZoneId to an Instant.
Example code:
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
ZoneId z = now.getZone();
ZoneRules zoneRules = z.getRules();
Boolean isDst = zoneRules.isDaylightSavings( now.toInstant() );
Note how in the last line we had to extract an Instant object from our ZonedDateTime object with a simple call to toInstant.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
You're going to have to do a bit more work using those coordinates and figure out which time zone they're in. Once you know which TimeZone that is, the isDayLight() method would be useful.
For example, you have no way of telling whether -0500 is EST (US/Canada Eastern Standard Time), CDT (US/Canada Central Daylight Time), COT (Colombia Time), AST (Brazil Acre Standard Time), ECT (Ecuador Time), etc...
Some of these may or may not support daylight saving time.
Joda Time contains handling methods which will calculate the offsets for you. See DateTimeZone.convertLocalToUTC(...)
To supplement this, you will need to look up the current time zone with your latitude/longitude info. GeoNames provides a java client for its web service, as well as a simple web-request framework (i.e. http://ws.geonames.org/timezone?lat=47.01&lng=10.2)