Skip to main content
added 157 characters in body
Source Link
Adrian Larson
  • 151.3k
  • 38
  • 247
  • 431

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer.

You also seem to have a fundamental misunderstanding about how the BusinessHours class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin method will always return false on those weekend days. It doesn't just check holidays.

Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    public static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
            
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsedpointer = 0;BusinessHours.nextStartDate(defaultHours.Id, pointer);
        while// make sure you're starting at a Datetime within BusinessHours

        for (Integer elapsed = 0; elapsed < daysdays; elapsed++)
        {
            pointer = pointer.addDays(1);
            if (!BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else    pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);

Note that the output is in GMT, so you may need to adjust it to include timezone offsets.

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer.

You also seem to have a fundamental misunderstanding about how the BusinessHours class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin method will always return false on those weekend days. It doesn't just check holidays.

Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
    
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsed = 0;
        while (elapsed < days)
        {
            pointer = pointer.addDays(1);
            if (BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer.

You also seem to have a fundamental misunderstanding about how the BusinessHours class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin method will always return false on those weekend days. It doesn't just check holidays.

Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    public static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
            
    public static Datetime add(Datetime pointer, Integer days)
    {
        pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        // make sure you're starting at a Datetime within BusinessHours

        for (Integer elapsed = 0; elapsed < days; elapsed++)
        {
            pointer = pointer.addDays(1);
            if (!BusinessHours.isWithin(defaultHours.Id, pointer))
                pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);

Note that the output is in GMT, so you may need to adjust it to include timezone offsets.

added 402 characters in body
Source Link
Adrian Larson
  • 151.3k
  • 38
  • 247
  • 431

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer.

You also seem to have a fundamental misunderstanding about how the BusinessHours class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin method will always return false on those weekend days. It doesn't just check holidays.

Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
    
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsed = 0;
        while (elapsed < days)
        {
            pointer = pointer.addDays(1);
            if (BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer. Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
    
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsed = 0;
        while (elapsed < days)
        {
            pointer = pointer.addDays(1);
            if (BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer.

You also seem to have a fundamental misunderstanding about how the BusinessHours class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin method will always return false on those weekend days. It doesn't just check holidays.

Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
    
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsed = 0;
        while (elapsed < days)
        {
            pointer = pointer.addDays(1);
            if (BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);
Source Link
Adrian Larson
  • 151.3k
  • 38
  • 247
  • 431

You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer counter variable for the number of days elapsed, then increment a Datetime pointer. Here's how I would write a utility class to calculate business days:

public class BusinessDays
{
    static BusinessHours defaultHours
    {
        get
        {
            if (defaultHours == null)
                defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
            return defaultHours;
        }
        private set;
    }
    
    public static Datetime add(Datetime pointer, Integer days)
    {
        Integer elapsed = 0;
        while (elapsed < days)
        {
            pointer = pointer.addDays(1);
            if (BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
            else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
        }
        return pointer;
    }
}

Then your code would simplify to:

Datetime dueDate = BusinessDays.add(createdDate, 3);