Your use of the date function is incorrect. See how the function argument specifies "string $format". I.e. the format parameter shoudl be a string which you do not supply.
Your logic is flawed.
1. date(G) != 'Sun
date('G') returns an integer representing the current hour of the day
Had you
2. date('G') != 'Sun' > 3 - see operator precedence
So, first: Is 'Sun' > 3? It isn't: value is false.
Then: is date('G') != false. It is not false, except from midnight to 1, non inclusive: value is true 23 hours per day, false 1 hour per day.
And then you have
date('G') < 4
So this part means, run the code if date('G') < 4 and with the above, that is from 1am to just before it turns 4:00:00.
Then you use && with this and date('D') != 'Sun'. In other words, run this code 6 days a week from 1am to 4 am (non inclusive).
Also had you gotten the hour comparison part "right", you'd be testing it for being > 3 and < 4 which it can never be. Being < 4, the greatest value it could take is 3, which can never be > 3. The integer for an hour has no notion of any minutes.
What you want is: run code if
1. not sunday
2 sunday, but not 3-4 am
$weekday = date('N');
if (7 != $weekday || (7 == $weekday && 3 != date('G')))
And you can always test this kind of code by assuming
1. should never be run today. Replace 7 with any day that today isn't.
2. Should not be run today if it is this particular hour. Replace 7 with whatever day of the week it really is and the hour with current hour.
Also why do string comparison of 'Sun' against 'Sun', when you can compare integers?