Update 26th Oct: See below for a second version following comments below
I have just promoted this idea as well, I would never have imagined it to be a good design for this method to have it throw an unhandled exception, IMHO that is!
Anyway, since we are being inventive here, the following also seems to do the trick. But be aware much like the custom setting counting trick, it does not actually reserve anything for the subsequent sending of emails, as the method call is made in another VF context.
<apex:page controller="TestMessagingLimitController" action="{!check}"/>
public with sharing class TestMessagingLimitController
{
public PageReference check()
{
Integer amount = Integer.valueOf(ApexPages.currentPage().getParameters().get('amount'));
Messaging.reserveSingleEmailCapacity(amount);
return null;
}
}
You can then do this...
try
{
PageReference checkMessages = Page.testmessaginglimit;
checkMessages.getParameters().put('amount', '1000');
checkMessages.getContent();
// Success (note messages will not be reserved however)
}
catch (Exception e)
{
// Failure
System.debug(e.getMessage());
}
Implementation Note: If you wrap the above in your own helper method, e.g.
public static boolean checkSingleEmailCapacity(Integer amount)
You can then easily switch out this implementation with a try/catch once Salesforce allows us to catch these exceptions or provides an alternative as per the idea exchange posting.
Hope this helps!
Update: Apex REST Approach
Here is a further approach that is using a Http callout. I've left the above approach in my answer, as it has the benefit of not needing a remote site enabled, global class etc. So please make your choice! In the end if you follow the abstraction I recommended above and only call the helper method you can change your mind swiftly in the future.
@RestResource(urlMapping='/MessageLimit')
global with sharing class MessageLimit
{
@HttpGet
global static void doGet()
{
RestRequest req = RestContext.request;
Integer amount = Integer.valueOf(req.params.get('amount'));
Messaging.reserveSingleEmailCapacity(amount);
}
public static boolean checkSingleEmailCapacity(Integer amount)
{
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/apexrest/MessageLimit?amount=' + amount);
req.setMethod('GET');
req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
HttpResponse res = h.send(req);
if(res.getStatusCode() == 500) // May want to actually check the body message to be 100% sure
return false;
return true;
}
}
Thus you can now do this!
if(MessageLimit.checkSingleEmailCapacity(1001))
System.debug('Good to go!');
else
System.debug('No go for launch!');
Enjoy!
The Timezone class does exactly what you are looking for. As far as I know, it covers the entire tz database, and I know that it covers some historical changes in the database, as shown below.
Timezone tz = Timezone.getTimeZone('America/New_York');
//before the 2007 shift of DST into November
DateTime dtpre = DateTime.newInstanceGMT(2000, 11, 1, 0, 0, 0);
system.debug(tz.getOffset(dtpre)); //-18000000 (= -5 hours = EST)
//after the 2007 shift of DST into November
DateTime dtpost = DateTime.newInstanceGMT(2012, 11, 1, 0, 0, 0);
system.debug(tz.getOffset(dtpost)); //-14400000 (= -4 hours = EDT)
It also gets the exact time at which DST starts or ends.
Timezone tz = Timezone.getTimeZone('America/New_York');
DateTime dtpre = DateTime.newInstanceGMT(2014, 11, 2, 5, 59, 59); //1:59:59AM local
system.debug(tz.getOffset(dtpre)); //-14400000 (= -4 hours = still on DST)
DateTime dtpost = DateTime.newInstanceGMT(2014, 11, 2, 6, 0, 0); //2:00:00AM local
system.debug(tz.getOffset(dtpost)); //-18000000 (= -5 hours = back one hour)
Best Answer
So you could do something like this:
Decimal MilliSeconds = EndTime.getTime() -StartTime.getTime() ; Decimal HourConvert = Millisecds / (1000.0*60.0*60.0)
When you use .getTime() it returns the number of Milliseconds since 1970.
Subtract the two to get the total milliseconds between the two dateTimes.
Then you take the milliseconds to calculate up to get your hours. 1000 (Seconds), * 60 (Minutes) * 60 (hours)
Edit Based On actually reading the questions correctly*
So the above gives you total time.
To get the Night/Day hours you need to break it up.
So that's the basis of this. Below is a class (Quick and Dirty) to do just what I listed above. What's not included is the Rounding up of the values.
}